1. 程式人生 > >天梯賽練習(一)

天梯賽練習(一)

從右到左 false bits ppr ret tro != quick 平面

L2-017. 人以群分

題意:

給定n個正整數, 然後分成規模相差盡可能接近的兩類, 這兩類之和相差要盡可能大

分析:

直接排序, 然後分成兩部分即可

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[123456];
 4 int sum(int l , int r){
 5     int ans = 0;
 6     for(int i = l; i <= r; i++) ans += a[i];
 7     return ans;
 8 }
 9 int main()
10 {
11     int
n; 12 scanf("%d", &n); 13 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 14 sort(a + 1, a + n + 1); 15 int mid = n / 2; 16 printf("Outgoing #: %d\nIntroverted #: %d\nDiff = %d\n",n-mid, mid, sum(mid+1, n) - sum(1,mid)); 17 return 0; 18 }
人以群分

L2-019. 悄悄關註

題意:

給定一個關註列表, 然後再給出一個對每個用戶的點贊數, 如果有一個對某一個用戶的點贊數大於平均值而且該用戶不在關註列表中, 輸出。

分析:

用一個set保存關註列表, 用一個map去儲存用戶點贊數, 最後遍歷一次map即可。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 set<string> focus; //關註列表
 4 map<string, int > like; //點贊數
 5 int main()
 6 {
 7     int n, m;
 8     cin >> n;
 9     string temp;
10     for(int i = 0; i < n; i++){
11         cin >> temp;
12 focus.insert(temp); 13 } 14 double sum = 0; 15 int a; 16 cin >> m; 17 for(int i = 0; i < m; i++){ 18 cin >> temp >> a; 19 like[temp] += a; 20 sum += a; 21 } 22 sum /= (double)m; 23 int flag = 0; 24 for(auto it = like.begin(); it != like.end(); it++){ 25 if(it->second > sum && !focus.count(it->first)) { 26 flag = 1; 27 cout << it->first << "\n"; 28 } 29 } 30 if(!flag) cout << "Bing Mei You\n"; 31 }
悄悄關註

L2-020. 功夫傳人

題意:

給定一個師傅徒弟家譜,每個師傅可以收很多個徒弟, 每個徒弟只能有一個師傅, 然後一開始有一個祖師爺有功力值Z。每代傳遞會有一個損耗r,徒弟有可能出現“得道者”會將功力放大k倍,但是“得道者”不會收徒弟, 求出“得道者”功力之和。

分析:

家譜成一個樹形結構, 用BFS遍歷一遍, 每次遇到“得道者”將功力加上即可。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 7;
 4 int n;
 5 double z, r;
 6 double quickpow(double a,int b)//快速冪
 7 {
 8     double ans = 1;
 9     while(b)//用一個循環從右到左便利b的所有二進制位
10     {
11         if(b&1)//判斷此時b[i]的二進制位是否為1
12         {
13             ans = (ans*a);//乘到結果上,這裏a是a^(2^i)%m
14             b--;//把該為變0
15         }
16         b/=2;
17         a = a*a;
18     }
19     return ans;
20 }
21 struct node{
22     int n, dynasty; //編號、 傳遞了幾代
23     node(int _n, int _dynasty):n(_n), dynasty(_dynasty){}
24 };
25 int F[maxn], master[maxn];
26 vector<int> apprentice[maxn];
27 int main()
28 {
29     scanf("%d %lf %lf", &n, &z, &r);
30     r = (100 - r)/100;
31     for(int i = 0; i < n; i++){
32         int num;
33         scanf("%d", &num);
34         if(num == 0){
35             int t;
36             scanf("%d", &t);
37             master[i] = t;
38         }
39         else{
40             for(int j = 0; j < num; j++){
41                 int t;
42                 scanf("%d", &t);
43                 apprentice[i].push_back(t);
44             }
45         }
46     }
47     double ans = 0;
48     queue<node> q;
49     q.push(node(0,0));
50     while(!q.empty()){
51         node u = q.front(); q.pop();
52         int name = u.n , d = u.dynasty
53         if(master[name])
54         {
55             ans += quickpow(r,d) * z * (double)master[name];
56         }
57         else
58         for(int i = 0; i < apprentice[name].size(); i++){
59             q.push(node(apprentice[name][i], d + 1));
60         }
61     }
62     printf("%d\n", (int)ans);
63     return 0;
64 }
功夫傳人

L3-013. 非常彈的球

題意:

給出一個球的質量, 求在一個平面拋出能得到的最遠距離。

分析:

技術分享圖片

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const double eps = 1e-6;
 4 int main()
 5 {
 6     double w, p, E, v, ans;
 7     scanf("%lf%lf", &w, &p);
 8     E = 1000, ans = 0;
 9     w /= 100;
10     do{
11         v = sqrt(2*E/w);
12         ans += v*v/9.8;
13         E *= ((100-p)/100);
14     }while(v > eps);
15     printf("%.3f", ans);
16 }
非常彈的球

L3-015. 球隊“食物鏈”

題意:

給定N支隊伍的2*N場雙循環賽結果, 求出一條包含所有球隊的“食物鏈”,“食物鏈”為一個1至N的排列{ T1 T2 ... TN },滿足:球隊T1戰勝過球隊T2,球隊T2戰勝過球隊T3,……,球隊T(N-1)戰勝過球隊TN,球隊TN戰勝過球隊T1。若存在多條“食物鏈”,請找出字典序最小的。

分析:

因為這條食物鏈如果存在, 那麽一定是包含所有球隊的, 所以可以從第一個點開始DFS,有一個剪枝是“如果還沒選擇的點沒有與1相連接的, 剪枝”。

另外要註意的是圖並不是對稱的, a輸b==b贏a。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 bool g[25][25];
 4 bool vis[25];
 5 int pick[25];
 6 int n, ok;
 7 bool dfs(int index , int tot)
 8 {
 9     if(tot == n){
10         if(g[index][0] == 1){
11             printf("%d", pick[0] + 1);
12             for(int i = 1; i < n; i++) printf(" %d", pick[i] + 1); puts("");
13             return true;
14         }
15         return false;
16     }
17     int cut = 1;//剪枝, 如果剩下沒挑選的點都沒有與1相連的,剪枝。
18     for(int i = 0; i < n; i++){
19         if(!vis[i] && g[i][0] == 1) {
20             cut = 0;
21             break;
22         }
23     }
24     if(cut) return false;
25     for(int i = 0; i < n; i++){
26         if(g[index][i] == 1 && !vis[i]){
27             vis[i] = 1;
28             pick[tot] = i;
29             if(dfs(i, tot + 1)) return true;
30             vis[i] = 0;
31         }
32     }
33     return false;
34 }
35 int main()
36 {
37     scanf("%d ", &n);
38     char input[123];
39     for(int i = 0; i < n; i++){
40         gets(input);
41         for(int j = 0; j < n; j++)
42             if( input[j] == W) g[i][j] = 1;
43             else if( input[j] == L) g[j][i] = 1;//註意a輸b其實等於b贏a
44     }
45     vis[0] = 1;
46     pick[0] = 0;
47     ok = dfs(0, 1);
48     if(!ok) printf("No Solution\n");
49 }
球隊“食物鏈”

天梯賽練習(一)