[Gym]2008-2009 ACM-ICPC, NEERC, Moscow Subregional Contest
比赛链接:http://codeforces.com/gym/100861
A模拟,注意两个特殊的缩写。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<string, string> pss; 5 const string MSU = "MSU"; 6 const string SCH = "SCH"; 7 const int maxn = 110; 8 map<string, int> school; 9 int n; 10 string a, b; 11 vector<pss> team; 12 vector<pss> ret; 13 14 string up(string x) { 15 int len = x.length(); 16 for(int i = 0; i < len; i++) { 17 if(x[i] >= 'a' && x[i] <= 'z') x[i] = x[i] - 'a' + 'A'; 18 } 19 return x; 20 } 21 22 int main() { 23 //freopen("in", "r", stdin); 24 while(~scanf("%d", &n)) { 25 school.clear(); team.clear(); ret.clear(); 26 for(int i = 1; i <= n; i++) { 27 cin >> a >> b; 28 team.push_back(pss(a, b)); 29 } 30 for(int i = 0; i < n; i++) { 31 string tmp = up(team[i].first); 32 if(team[i].first == SCH) continue; 33 if(school.find(tmp) == school.end()) { 34 ret.push_back(team[i]); 35 school[tmp] = 1; 36 continue; 37 } 38 if(team[i].first == MSU) { 39 if(school[tmp] < 4) { 40 ret.push_back(team[i]); 41 school[tmp]++; 42 } 43 } 44 else { 45 if(school[tmp] < 2) { 46 ret.push_back(team[i]); 47 school[tmp]++; 48 } 49 } 50 } 51 if(ret.size() <= 10) { 52 printf("%d\n", ret.size()); 53 for(int i = 0; i < ret.size(); i++) { 54 cout << ret[i].first <<" " << ret[i].second << endl; 55 } 56 } 57 else { 58 printf("%d\n", 10); 59 for(int i = 0; i < 10; i++) { 60 cout << ret[i].first <<" " << ret[i].second << endl; 61 } 62 } 63 } 64 return 0; 65 }
B排序+离散化
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 typedef struct F { 6 int idx; 7 LL val; 8 }F; 9 typedef struct S { 10 int idx; 11 int val; 12 }S; 13 const int maxn = 10100; 14 const int maxm = 70070; 15 S s[maxm]; 16 int k; 17 int n, m; 18 LL a, b, c; 19 F f[maxm]; 20 LL ret[maxm]; 21 22 int h[maxm], hcnt; 23 int t[maxm], tcnt; 24 25 bool cmp1(S a, S b) { 26 if(a.val == b.val) return a.idx < b.idx; 27 return a.val > b.val; 28 } 29 30 bool cmp2(F a, F b) { 31 if(a.val == b.val) return a.idx < b.idx; 32 return a.val > b.val; 33 } 34 35 int id(int x) { 36 return lower_bound(h, h+hcnt, x) - h + 1; 37 } 38 39 int main() { 40 freopen("in", "r", stdin); 41 int x; 42 while(~scanf("%I64d%I64d%I64d%I64d",&f[1].val,&a,&b,&c)) { 43 memset(ret, 0, sizeof(ret)); 44 k = 0; hcnt = 0, tcnt = 0; 45 for(int i = 0; i < maxm; i++) { 46 s[i].idx = -1; 47 s[i].val = 0; 48 } 49 scanf("%d%d",&n,&m); 50 for(int i = 1; i <= n; i++) { 51 for(int j = 1; j <= m; j++) { 52 scanf("%d", &x); 53 t[tcnt++] = x; 54 h[hcnt++] = x; 55 } 56 } 57 sort(h, h+hcnt); hcnt = unique(h, h+hcnt) - h; 58 for(int i = 0; i < tcnt; i++) { 59 if(s[id(t[i])].idx == -1) { 60 k++; 61 s[id(t[i])].idx = t[i]; 62 } 63 s[id(t[i])].val++; 64 } 65 sort(s+1, s+maxm, cmp1); 66 f[1].idx = 1; 67 for(int i = 2; i <= k; i++) { 68 f[i].idx = i; 69 f[i].val = ((a * f[i-1].val + b) % c) + 1; 70 } 71 sort(f+1, f+k+1, cmp2); 72 for(int i = 1; i<= k; i++) { 73 ret[f[i].idx] = s[i].idx; 74 } 75 printf("%d\n", k); 76 for(int i = 1; i<= k; i++) { 77 printf("%I64d%c", ret[i], i == k ? '\n' : ' '); 78 } 79 } 80 return 0; 81 }
C贪心,就像搭积木一样,全是1*1*1的小方块,要想让表面积尽可能小,那就把他们往一个角落堆。比如
3 3
1 2 3 4 5 6 7 8 9这样的数据,那么排出来就是。
9 8 5
7 6 4
3 2 1
这样可以保证遮盖的部分最大。那么只需要找到第一行和第一列的高度,两边加起来乘2就行了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 330; 5 int n, m, k; 6 int t[maxn*maxn]; 7 8 int main() { 9 // freopen("in", "r", stdin); 10 while(~scanf("%d%d",&m,&n)) { 11 k = 0; 12 if(m < n) swap(m, n); 13 for(int i = 1; i <= m; i++) { 14 for(int j = 1; j <= n; j++) { 15 scanf("%d",&t[k++]); 16 } 17 } 18 sort(t, t+k, greater<int>()); 19 int ret = 0; 20 for(int i = 0; i < n; i++) { 21 ret += t[i*i]; 22 ret += t[i*(i+1)]; 23 } 24 for(int i = n; i < m; i++) { 25 ret += t[i*n]; 26 } 27 cout << ret * 2 << endl; 28 } 29 return 0; 30 }
G首先知道结果为0的情况,那就是小于等于3个点的时候;想要结果为1,那么必然是两两配对出来的新点位置重合。否则可以让任意四个点组成一个四边形,这个时候分别取每边的中点,构成的四边形一定是平行四边形(很好证明)。所以第二次就一定会有交点了(对角线中心)。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int,int> pii; 5 const int maxn = 1010; 6 int n; 7 int x[maxn], y[maxn]; 8 map<pii, bool> s; 9 10 int main() { 11 // freopen("in", "r", stdin); 12 while(~scanf("%d", &n)) { 13 s.clear(); 14 for(int i = 1; i <= n; i++) { 15 scanf("%d%d",&x[i],&y[i]); 16 x[i] <<= 1; y[i] <<= 1; 17 } 18 if(n <= 3) { 19 puts("0"); 20 continue; 21 } 22 bool flag = 0; 23 for(int i = 1; i <= n; i++) { 24 if(flag) break; 25 for(int j = i+1; j <= n; j++) { 26 int tx = (x[i] + x[j]) / 2; 27 int ty = (y[i] + y[j]) / 2; 28 if(s.find(pii(tx, ty)) != s.end()) { 29 printf("1\n"); 30 flag = 1; 31 break; 32 } 33 s[pii(tx, ty)] = 1; 34 } 35 } 36 if(!flag) puts("2"); 37 } 38 return 0; 39 }
L打表找规律,然后就很简单了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1000100; 5 bool vis[maxn]; 6 7 bool lucky(int s) { 8 int x, y; 9 x = s % 1000; 10 s /= 1000; 11 y = s; 12 int sx = 0, sy = 0; 13 while(x) { 14 sx += x % 10; 15 x /= 10; 16 } 17 while(y) { 18 sy += y % 10; 19 y /= 10; 20 } 21 return sx == sy; 22 } 23 24 int main() { 25 memset(vis, 0, sizeof(vis)); 26 for(int i = 100000; i <= 999999; i++) { 27 vis[i] = lucky(i); 28 } 29 int ret = 0; 30 int tmp = 0; 31 int rl ,rh; 32 int lo; 33 lo = 100000; 34 for(int i = 100000; i <= 999999; i++) { 35 if(vis[i]) { 36 if(ret < tmp) { 37 rl = lo; 38 rh = i - 1; 39 ret = tmp; 40 } 41 tmp = 0; 42 lo = i + 1; 43 } 44 else { 45 tmp++; 46 } 47 } 48 cout <<ret <<endl; 49 cout << rl << " " << rh << endl; 50 }
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 string ret[200][200] = { 5 {"0","0"}, 6 {"89","98"}, 7 {"9899","9998"}, 8 {"998999","999998"}, 9 {"99989999","99999998"}, 10 {"9999899999","9999999998"}, 11 {"999998999999","999999999998"}, 12 {"99999989999999","99999999999998"}, 13 {"9999999899999999","9999999999999998"}, 14 {"999999998999999999","999999999999999998"}, 15 {"99999999989999999999","99999999999999999998"}, 16 }; 17 int main() { 18 int n; 19 while(~scanf("%d", &n)) { 20 cout << ret[n][0] << endl << ret[n][1] << endl; 21 } 22 }