cumt2017春季——周练
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cumt2017春季——周练相关的知识,希望对你有一定的参考价值。
A.Bear and Big Brother
1 #include <bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int x, y; 6 scanf("%d%d", &x, &y); 7 8 int ans = 0; 9 while(x <= y) 10 { 11 x *= 3; 12 y *= 2; 13 ans++; 14 } 15 printf("%d\n", ans); 16 return 0; 17 }
B.The Monster(暴力)
题意:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int a, b, c, d; 5 6 int solve() 7 { 8 map<int, int>ma; 9 int y = b; 10 while(y <= 10000) 11 { 12 ma[y]++; 13 y += a; 14 } 15 16 y = d; 17 while(y <= 10000) 18 { 19 if(ma[y] != 0) return y; 20 y += c; 21 } 22 return -1; 23 } 24 25 int main() 26 { 27 scanf("%d%d%d%d", &a, &b, &c, &d); 28 printf("%d\n", solve()); 29 return 0; 30 }
C.Bear and Friendship Condition(并查集)
题意:
如果1认识2,2认识3,必须要求有:1认识3.如果满足上述条件,输出YES,否则输出NO.
思路:
拿并查集维护朋友关系,维护并查集的同时维护一个cnt数组,cnt[root]代表以root为根节点的并查集的大小是cnt[root]个。那么验证是否整张图满足条件的方法就是,对于任意一个点i,它的度数应该是cnt[ pa[i] ] - 1。即,它所在的朋友圈有k人,则它应该有k-1条边。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 150000 + 5; 4 int pa[maxn]; 5 set<int>G[maxn]; 6 int cnt[maxn]; 7 void init(int n) 8 { 9 for(int i = 0; i <= n; i++) pa[i] = i, cnt[i] = 1; 10 } 11 int uf_find(int x){return x == pa[x] ? x : (pa[x] = uf_find(pa[x]));} 12 13 void uf_join(int x, int y) 14 { 15 int fx = uf_find(x), fy = uf_find(y); 16 if(fx != fy) 17 pa[fx] = fy, cnt[fy] += cnt[fx]; 18 } 19 20 bool judge(int n) 21 { 22 for(int i = 1; i <= n; i++) 23 { 24 int fi = uf_find(i); 25 if(i != fi && G[i].size() + 1 != cnt[fi]) 26 { 27 return false; 28 } 29 } 30 return true; 31 } 32 int main() 33 { 34 init(150000); 35 int n, m; 36 scanf("%d%d", &n, &m); 37 for(int i = 0; i < m; i++) 38 { 39 int x, y; 40 scanf("%d%d", &x, &y); 41 G[x].insert(y); 42 G[y].insert(x); 43 uf_join(x, y); 44 } 45 if(judge(n)) puts("YES"); 46 else puts("NO"); 47 48 return 0; 49 }
F.UVA 10970(思维)
题意:
给你一块M*N的巧克力,问把它切成最小单元需要最少切几刀,分开的就不能一起切了。
思路:
每次下刀,只能多增加一块,一共需要切成m*n块,所以显然答案。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 1000000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 11 int main() 12 { 13 int n, m; 14 while(cin >> n >> m) cout << n * m - 1 << endl; 15 return 0; 16 }
G.UVA - 10340(经典问题)
题意:
从字符串s中删除一些字符,能否得到字符串t。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 1000000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 bool solve(string &s, string &t) 11 {//从t中删除 能否得到s 12 int lens = s.length(), lent = t.length(); 13 int cnt = 0; 14 for(int i = 0; i < lent; i++) 15 { 16 if(s[cnt] == t[i]) cnt++; 17 } 18 return cnt == lens; 19 } 20 21 int main() 22 { 23 string a, b; 24 while(cin >> a >> b) 25 { 26 printf("%s\n", solve(a, b) ? "Yes" : "No"); 27 } 28 return 0; 29 }
H.UVA 10382(经典贪心)
题意:
有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆。求出最少需要的喷水装置个数。
思路:
每个圆,和草坪边界交点,化成一个线段,然后问题就变成,最少需要几个小区间覆盖整个大区间。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 10000 + 5; 6 const int INF = 0x3f3f3f3f; 7 const double eps = 1e-8; 8 typedef pair<int, int>pii; 9 typedef pair<double, double>pdd; 10 typedef long long LL; 11 typedef unsigned long long ull; 12 13 int n, l; 14 double w; 15 pdd a[maxn]; 16 17 bool cmp(pii x, pii y) 18 { 19 if(x.first != y.first) return x.first < y.first; 20 return x.second < y.second; 21 } 22 23 int solve() 24 { 25 double last, temp; 26 if(a[0].first - 0 > eps) return -1; 27 28 int ans = 0; 29 double cur = 0, far = 0; 30 for(int i = 0; i < n; i++) 31 { 32 if(cur >= l) return ans; 33 if(a[i].first <= cur) 34 { 35 far = max(far, a[i].second); 36 } 37 else if(a[i].first > cur) 38 { 39 ans++; 40 cur = far; 41 if(a[i].first <= cur) 42 { 43 far = max(far, a[i].second); 44 } 45 else 46 { 47 return -1; 48 } 49 } 50 } 51 if(cur < l && far >= l) return ans + 1; 52 if(far < l) return -1; 53 return ans; 54 } 55 56 int main() 57 { 58 59 while(~scanf("%d%d%lf", &n, &l, &w)) 60 { 61 for(int i = 0; i < n; i++) 62 { 63 double pos, r; 64 scanf("%lf%lf", &pos, &r); 65 double d = sqrt(r * r - w / 2 * w / 2); 66 a[i].first = pos - d, a[i].second = pos + d; 67 } 68 sort(a, a + n, cmp); 69 70 cout << solve() << endl; 71 72 73 } 74 return 0; 75 }
I.UVA 10905
题意:
给n个数字,将它们重新排序得到一个最大的数字,比如给出123 456 789 拼为 789456123 最大。
思路:
两两贪心!
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int mod = 1e9 + 7; 4 const int maxn = 50 + 5; 5 const int INF = 0x3f3f3f3f; 6 typedef long long LL; 7 typedef unsigned long long ull; 8 9 10 string num[maxn]; 11 bool cmp(string &a, string &b) 12 { 13 return a + b > b + a; 14 } 15 int main() 16 { 17 int n; 18 while(~scanf("%d", &n)) 19 { 20 if(n == 0) break; 21 for(int i = 0; i < n; i++) 22 { 23 cin >> num[i]; 24 } 25 sort(num, num + n, cmp); 26 for(int i = 0; i < n; i++) 27 { 28 cout << num[i]; 29 } 30 puts(""); 31 } 32 33 return 0; 34 }
J.Bear and Different Names(构造)
题意:
连续k个人不可有相同的名字
思路:
先这样考虑,把1-n的位置置为1,2,3,...,n。
那么显然,如果是YES,则一直满足条件,保持不变就好了。如果当前位置是i,指令为NO,那么我们要做一些什么更改呢,只要需要把[i,i + k -1]这k个数中的最后一个数字,a[i + k - 1] = a[i]。满足了当前区间是NO,且自i+1到n仍保持原来的属性,一直为YES。就这样就能构造出一个满足条件的序列了。
然后暴力搞个随机,打个名字的表就行了。这个表就相当于1,2,3,4,...,n。
1 #include <bits/stdc++.h> 2 using namespace std; 3 string name[205] = {"x", "Aa", "Bb" , "Cc", "Dd", "Ee" , "Ff" ,"Gg" , "Hh" , "Aaahglnt", "Aabgrtea", "Aafonkti", "Aawqffot", "Abrdbgnk", "Abyjfndo", "Accpphya", "Acgomdfb", "Acluatrp", "Acqsuwoo", "Acycmioj", "Adbbnytt", "Adezrgnv", "Adpxbmca", "Adrwxynk", "Adsnvthx", "Aduyfgmr", "Adxqjpat", "Aelugsgs", "Aewdbttu", "Afedjbpj", "Afkxdttk", "Afnvzafm", "Afwuokpd", "Afzdheck", "Agbifunf", "Ageroseh", "Aglaxgkb", "Agtugeun", "Ahciylyk", "Ahmotmkm", "Ahvmlmgd", "Aibzmjut", "Aietskor", "Aijobbfm", "Aiwqoywv", "Aizqcqyk", "Ajdcuoru", "Ajhcougy", "Ajqgndza", "Akcwqtid", "Akqqmuds", "Albduoty", "Alouzmpd", "Alyfdfht", "Amasunlb", "Amfxvkla", "Amqdqqev", "Amzwqtac", "Annzdvny", "Anwaoawm", "Aoovgcnb", "Apenhcdf", "Apksqkac", "Apycnnpq", "Aqizeqkf", "Aqjdpzvz", "Aqjjjsti", "Aqzpxguv", "Arfpgnot", "Ariqfihl", "Arjiqibc", "Arnqekvn", "Arqbkcaz", "Arrehjpl", "Arrlxuye", "Asgvgjfs", "Asiscmhj", "Asrmwabq", "Asvltjfr", "Asygsfgd", "Atigqiad", "Atnjqfhz", "Atpnekrx", "Atssgtgi", "Attpyxgu", "Auistszb", "Aumsoyfg", "Auvcsdfw", "Avckiwod", "Avdzmoya", "Avghyxfs", "Avpxrnmj", "Avuluuib", "Avydzsuu", "Avzpiaan", "Awbsnegp", "Awfwltto", "Awkrjqfk", "Awyqizql", "Awzvzzow", "Axkjllvg", "Axkoiemu", "Axqdgzee", "Aydinhlv", "Aythxbyg", "Azilfijf", "Azjgihgu", "Aztmjzrk", "Azzbiwet"}; 4 int main() 5 { 6 int n, k; 7 scanf("%d%d", &n, &k); 8 9 for(int i = 1; i <= n - k + 1; i++) 10 { 11 char s[20]; 12 scanf("%s", s); 13 if(s[0] == ‘N‘)//NO 14 { 15 name[i + k - 1] = name[i]; 16 } 17 } 18 for(int i = 1; i <= n; i++) 19 { 20 cout << name[i] <<(i == n ? ‘\n‘ : ‘ ‘); 21 } 22 return 0; 23 }
以上是关于cumt2017春季——周练的主要内容,如果未能解决你的问题,请参考以下文章