Codeforces Round #515(div.3)
結果は2完。まあ収穫はあったと思って諦めるしかない
追記:A問題は下のリンク先のように実装した方が楽です。
http://codeforces.com/contest/1066/submission/44251054
A問題は僕がよく引っかかる区間の問題。no submitも考慮したが、それでもシンプルに書く方法だけは考える。半開区間の端点上にvの倍数があった場合の切り上げ、切り捨ての扱いに気をつけ、次のコードでAC
#include<cstdio> using namespace std; typedef long long int ll; int t; int main(){ scanf("%d", &t); for(int i = 0; i < t; i++){ int L, v, l, r; scanf("%d %d %d %d", &L, &v, &l, &r); int O = 1; L -= L % v; r -= r % v; l += (l % v == 0 ? 0 : v - (l % v)); O += (O % v == 0 ? 0 : v - (O % v)); printf("%d\n", (L - r) / v + (l - O) / v); } return 0; }
B問題は貪欲。いろいろと実装ミスもあったが、一番痛いのは前にあるヒーターからチェックしていったこと。
これだと"5 2\n1 1 1 1 1"のようなケースで3などと出力するので、「暖まっていない部屋があったら、その部屋から(indexが増える方向に)なるべく遠くにあるヒーターを付ける」方針にすべき。
#include<cstdio> #include<algorithm> using namespace std; typedef long long int ll; int n, r; int a[1100]; bool visited[1100]; bool need[1100]; int main(){ scanf("%d %d", &n, &r); for(int i = 0; i < n; i++) scanf("%d", &a[i]); fill(visited, visited + n, false); fill(need, need + n, false); for(int i = 0; i < n; i++){ if(!visited[i]){ for(int j = min(n - 1, i + r - 1); j >= max(0, i - r + 1); j--){ if(a[j] == 1){ need[j] = true; for(int k = max(0, j - r + 1); k <= min(n - 1, j + r - 1); k++) visited[k] = true; break; } } } } int res = 0; for(int i = 0; i < n; i++){ if(!visited[i]){ printf("-1\n"); return 0; } if(need[i]) res++; } printf("%d\n", res); return 0; }