[GCJ] Qualification Round 2017

链接:https://code.google.com/codejam/contest/3264486/dashboard#s=p0

A.贪心,遇到-的就翻k个, 翻到最后看看是不是都是+。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 1100;
 6 int n, k;
 7 int a[maxn];
 8 char tmp[maxn];
 9 
10 int main() {
11     freopen("in", "r", stdin);
12     freopen("out", "w", stdout);
13     int T, _ = 1;
14     scanf("%d", &T);
15     while(T--) {
16         scanf("%s %d", tmp, &k);
17         n = strlen(tmp);
18         int ret = 0;
19         for(int i = 0; i < n; i++) a[i] = (tmp[i] == '+') ? 1 : 0;
20         for(int i = 0; i < n - k + 1; i++) {
21             if(a[i] == 0) {
22                 ret++;
23                 for(int j = i; j < i + k; j++) a[j] = 1 - a[j];
24             }
25         }
26         cout << "Case #" << _++ << ": ";
27         bool ok = 1;
28         for(int i = 0; i < n; i++) if(a[i] == 0) ok = 0;
29         if(!ok) puts("IMPOSSIBLE");
30         else printf("%d
", ret);
31     }
32     return 0;
33 }

B.小数据直接从n减到第一个符合条件为止。大数据可以从头到尾扫,遇到第一对不符合条件的数字就借位并且将后面所有位都置成9,循环扫直到不修改为止。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 32;
 6 char s[maxn];
 7 int n;
 8 
 9 int main() {
10     freopen("in", "r", stdin);
11     freopen("out", "w", stdout);
12     int T, _ = 1;
13     scanf("%d", &T);
14     while(T--) {
15         scanf("%s", s);
16         cout << "Case #" << _++ << ": ";
17         bool ok = 1;
18         n = strlen(s);
19         for(int i = 0; i < n - 1; i++) {
20             if(s[i] > s[i+1]) {
21                 ok = 0;
22                 break;
23             }
24         }
25         if(ok) puts(s);
26         else {
27             bool done = 1;
28             int pos = 1;
29             while(1) {
30                 for(int i = 0; i < n; i++) {
31                     if(s[i] < s[i-1]) {
32                         done = 0;
33                         pos = i;
34                         s[pos-1]--;
35                         for(int j = pos; j < n; j++) s[j] = '9';
36                         break;
37                     }
38                 }
39                 if(done) break;
40                 done = 1;
41             }
42             int p = 0;
43             while(s[p] == '0') p++;
44             puts(s+p);
45         }
46     }
47     return 0;
48 }

C.每次切分会变成两段,由于条件限制所以人一定会在长的那段里选(这样是最优的),因此小数据可以丢到堆里模拟k次,最后一次更新答案(堆里维护的每一个节点包括该段的最左最右的编号)。

由于每次拆出的段的选择总是同一种选择,所以直接记录每种长度的段出现几次,从大到小选第k段就行。需要一边更新一边判断以便记录解。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     int l, r;
 6     Node() {}
 7     Node(int l, int r) : l(l), r(r) {}
 8     friend bool operator<(const Node a, const Node b) {
 9         if(a.r-a.l != b.r-b.l) return a.r-a.l < b.r-b.l;
10         if(a.l != b.l) return a.l < b.l;
11         return a.r < b.r;
12     }
13 }Node;
14 
15 int n, k;
16 priority_queue<Node> pq;
17 
18 int main() {
19     freopen("in", "r", stdin);
20     freopen("out", "w", stdout);
21     int T, _ = 1;
22     scanf("%d", &T);
23     while(T--) {
24         scanf("%d%d",&n,&k);
25         while(!pq.empty()) pq.pop();
26         pq.push(Node(1, n));
27         for(int i = 0; i < k-1; i++) {
28             Node t = pq.top(); pq.pop();
29             int cut = (t.l + t.r) / 2;
30             if(t.l <= cut - 1) pq.push(Node(t.l, cut-1));
31             if(cut + 1 <= t.r) pq.push(Node(cut+1, t.r));
32         }
33         Node t = pq.top(); pq.pop();
34         int cut = (t.l + t.r) / 2;
35         int l = cut - t.l;
36         int r = t.r - cut;
37         printf("Case #%d: ", _++);
38         cout << max(l, r) << " " << min(l, r) << endl;
39     }
40     return 0;
41 }
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 LL n, k;
 6 unordered_map<LL, LL> vis;
 7 set<LL> s;
 8 
 9 int main() {
10     freopen("in", "r", stdin);
11     freopen("out", "w", stdout);
12     int T, _ = 1;
13     scanf("%d", &T);
14     while(T--) {
15         cin >> n >> k;
16         vis.clear(); s.clear();
17         printf("Case #%d: ", _++);
18         s.insert(n);
19         LL l, r, cnt = 0;
20         vis[n] = 1;
21         while(1) {
22             LL mid = *s.rbegin();
23             if((mid - 1) & 1) {
24                 l = (mid - 1) / 2;
25                 r = mid / 2;
26             }
27             else l = r = (mid - 1) / 2;
28             cnt += vis[mid];
29             if(cnt >= k) break;
30             s.erase(mid);
31             s.insert(l); s.insert(r);
32             vis[l] += vis[mid]; vis[r] += vis[mid];
33         }
34         cout << max(l, r) << " " << min(l, r) << endl;
35     }
36     return 0;
37 }
原文地址:https://www.cnblogs.com/kirai/p/6684977.html