2014微軟程式設計之美複賽的解題報告

2022-05-23 14:48:11 字數 4401 閱讀 3636

程式設計之美複賽做出三個題目,比賽結束後,和集訓隊的隊友討論了一番,最終得出解題的結論

現附上第一題,第三題,第四題的解題報告。

2014微軟程式設計之美 複賽 第一題:組隊

時間限制:2000ms

單點時限:1000ms

記憶體限制:256mb

有n支隊伍,每個隊伍有ai個選手。

現在,這n支隊伍想要進行交流:隊伍之間交換選手,使得交換完後,每個隊伍有且僅有1人和之前不同。

所以我們想知道,總共存在多少種可行的交換方案。兩種交換方案不同,當且僅當,交換後的至少有一支隊伍人員的集合不同。

第一行乙個整數t (1 ≤ t ≤ 10),表示資料組數。

接下來是t組輸入資料,測試資料之間沒有空行。

每組資料格式如下:

第一行乙個整數n 。第二行n個整數,ai (1 ≤ ai≤ 100)

對每組資料,先輸出「case x: 」,x表示是第幾組資料。然後輸出乙個整數,表示有多少種可行的交換方案。由於答案可能很大,只需要輸出除以109+7之後的餘數即可。

小資料:1 ≤ n ≤ 10

大資料:1 ≤  n ≤ 100

3 * 3種交換方法都行。

樣例輸入

1

23 3

樣例輸出

//by wangruixing

#include

#include

#include

#define p 1000000007

#define ll long long

#define n 160

using namespace std;

ll f[n];

int main()

* distance(i, j)的最大值。

第一行乙個整數t (1 ≤ t ≤ 10),表示資料組數。

接下來是t組輸入資料,測試資料之間沒有空行。

每組資料格式如下:

第一行乙個整數n ,表示有n個節點。

第二行n個整數,分別表示weight(i) (1 ≤ weight(i) ≤ 10^9)。

接下來n - 1行,每行3個整數a, b, c (1 ≤ a, b ≤ n, 1 ≤ c ≤ 104),表示節點a和b之間有一條權值為c的邊。

對每組資料,先輸出「case x: 」,x表示是第幾組資料,然後輸出最大值即可。

小資料:1 ≤ n ≤ 1000

大資料:1 ≤ n ≤ 105

只有i = 1, j = 2的可選方案,distance(1, 2) = 1, min = 1,所以最大值為1。

樣例輸入

1

21 2

1 2 1

樣例輸出

case 1: 1

這個題目很厲害,我學會了一種方法,以前不知道的,就是轉移樹的重心。

ac**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

#define all(a) a.begin(),a.end()

#define clr(a) memset(a,0,sizeof(a))

#define fill(a,b) memset(a,b,sizeof(a))

#define pb push_back

#define mp make_pair

typedef long long ll;

typedef vectorvi;

typedef pairpii;

typedef vector> vii;

const double eps = 1e-8;

const double pi = acos(-1.0);

const int mod = 1e9+7;

const int n = 100000 + 10;

typedef vector>::iterator it;

struct st st[n<<2];

vector> vec[n];

int m[n];

int w[n], dis[n], is[n], nid[n];

bool del[n];

int size[n], opt[n];

vi all, nn;

long long ans = 0;

void calc(int u, int fa)

int mark;

void go(int u, int par)}}

void build(int l, int r, int i)

int ask(int l, int r, int i)

int mid = (st[i].l+st[i].r)>>1;

if(r<=mid) return ask(l, r, i<<1);

else if(l>mid) return ask(l, r,i<<1|1);

else return max(ask(l,mid,i<<1),ask(mid+1,r,i<<1|1));

}void make(int x, int val, int i)

int mid = (st[i].l+st[i].r)>>1;

if(x<=mid) make(x, val, i<<1);

else make(x, val, i<<1|1);

st[i].mm = max(st[i<<1].mm, st[i<<1|1].mm);

}void dfs(int u, int par)

}nid[u] = 0;

build(0, idx, 1);

for(i=0;idel[u] = 1;

for(it e = vec[u].begin(); e != vec[u].end(); ++e)

}int main()

for(i=1;i第四題:廣場建設

時間限制:2000ms

單點時限:1000ms

記憶體限制:256mb

在某個外星城市中,有n個居民點,他們分布在三維空間裡,座標分別為(xi, yi, zi) (i = 1, 2, … ,n)。現在我們要建乙個廣場,廣場是通過原點的乙個平面ax + by + cz = 0(a, b, c不全為0)。請你幫忙確定這個廣場的傾斜方向,使得n個居民點到廣場的距離的平方和最小。

輸入包含多組測試資料,第一行是乙個整數t (1 ≤ t ≤ 10),表示測試資料組數。

對於每組測試資料:

第一行是乙個整數n,表示點的個數。(1 ≤ n ≤ 100)

接下來的n行,每行三個整數x, y, z,之間用乙個空格分隔。

對每組測試資料輸出一行,格式為「case x: a b c」。x表示測試資料組數,a, b, c的意義見題目描述,輸出任意一組解即可。如果根據答案所計算的距離平方和與最優解的絕對誤差或相對誤差在10-6以內,則認為答案正確。

小資料:1 ≤ n ≤ 2

大資料:1 ≤ n ≤ 100

樣例輸入

2

20 0 1

0 1 0

20 0 0

0 0 0

樣例輸出

case 1: 1.0 0.0 0.0

case 2: 1.0 0.0 0.0

這個題目真是讓我長見識了,用到了隨機演算法,一般很少用,先隨機演算法得到一些點,通過二分來縮小範圍,當縮小到乙個精度範圍內,就得出所要的點,這個方法比較巧妙,在計算幾何裡面經常會用到。這個題當時只a掉了小資料,沒有想到這種方法,現在分享給大家。

ac**:

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

const double eps = 1e-10 ;

int sgn(double x)

struct pt

pt (double x, double y, double z) : x(x), y(y), z(z) {}

} ;pt pt[105];

double x2, y2, z2, xy, xz, yz;

double work(pt pp)

int main()

}printf("case %d: ", cas);

printf("%.8f %.8f %.8f\n", bt.x, bt.y, bt.z);

}return 0;

}

微軟程式設計之美 初賽

相似字串對於兩個長度相等的字串,我們定義其距離為對應位置不同的字元數量,同時我們認為距離越近的字串越相似。例如,0123 和 0000 的距離為 3,0123 和 0213 的距離則為 2,所以與 0000 相比,0213 和 0123 最相似。現在給定兩個字串 s1 和 s2,其中 s2 的長度不...

微軟程式設計之美2013全國挑戰賽 複賽 第2題

include 微軟程式設計之美2013全國挑戰賽複賽第2題 由於比賽結束後,提交入口關閉,沒來得及提交,但本地資料測試是沒錯的,不知道能否ac include includeusing namespace std struct yingxiangli int main else for int n...

程式設計之美 微軟技術面試心得

內容介紹 第1章 遊戲之樂 遊戲中碰到的題目.1 1.1 讓cpu佔用率曲線聽你指揮.3 1.2 中國象棋將帥問題.13 1.3 一摞烙餅的排序.20 1.4 買書問題.30 1.5 快速找出故障機器.35 1.6 飲料供貨.40 1.7 光影切割問題.45 1.8 小飛的電梯排程演算法.50 1....