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;
}