链接: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 }