Codeforces 1692 (Div.4) C-E

先赞后看,已成习惯……


C

分析一下题目中的样例。
image
其中红色表示象的位置。
有没有发现,绿色的位置都被标记了?
是的!象的特点就是
左上,右上,左下,右下
都会被标记!

#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <bitset>
#include <stack>
#include <sstream>
#include <algorithm>

#define INF 1000000007
#define MOD 998244353

using namespace std;

char chess[10][10];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		getchar();
		for (int i = 0; i < 8; i++) {
			getchar();
			for (int j = 0; j < 8; j++) {
				chess[i][j] = getchar();
			}
		}
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				if (chess[i][j] == '#') {
					if (chess[i - 1][j - 1] == '#'
					&&  chess[i - 1][j + 1] == '#'
					&&  chess[i + 1][j - 1] == '#'
					&&  chess[i + 1][j + 1] == '#') {
						printf("%d %d\n", i + 1, j + 1);
						goto end;
					}
				}
			}
		}
		end:;
	}
	return 0;
}

D

直接暴力就行了。
注意要及时取模。
这里我采用了1440分钟表示时间的方法。

#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <bitset>
#include <stack>
#include <sstream>
#include <algorithm>

#define INF 1000000007
#define MOD 998244353

using namespace std;

// 00:00 25

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int hh, mm;
		scanf("%02d:%02d", &hh, &mm);
		int time_007 = hh * 60 + mm;
		int x;
		scanf("%d", &x);
		int ans = 0;
		if (hh / 10 == mm % 10 && mm / 10 == hh % 10) {
			ans = 1;
		}
		for (int now_time = (time_007 + x) % 1440; now_time != time_007; now_time = (now_time + x) % 1440) {
			int h = now_time / 60;
			int m = now_time % 60;
			if (h / 10 == m % 10 && m / 10 == h % 10) {
				ans++;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

E

重头戏来了!
首先我们统计出前缀和和后缀和。
原数组:0 1 1 0 0 1 1 0 0 1
前缀和:0 1 2 2 2 3 4 4 4 5
后缀和:5 5 4 3 3 3 2 1 1 1
如果1的个数 $ < s $ 就死了。
否则要删的1的个数就是1的个数 - s。
先统计一遍前面第一个前缀和有多少的 的位置。
再统计一遍后面最后一个后缀和有多少的 的位置。
我们枚举前面要删多少个,后面要删多少个。
然后两边一加,嘭!

#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <bitset>
#include <stack>
#include <sstream>
#include <algorithm>

#define INF 1000000007
#define MOD 998244353

using namespace std;

#define maxn 200005

int pre1[maxn], suf1[maxn];
int prefix[maxn], suffix[maxn];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		memset(pre1, 0x3f, sizeof(pre1));
		memset(suf1, 0, sizeof(suf1));
		memset(prefix, 0, sizeof(prefix));
		memset(suffix, 0, sizeof(suffix));
		int n, s;
		scanf("%d %d", &n, &s);
		for (int i = 0; i < n; i++) {
			scanf("%d", &prefix[i]);
			suffix[i] = prefix[i];
		}
		n++;
		for (int i = 1; i < n; i++) {
			prefix[i] += prefix[i - 1];
		}
		for (int i = n - 2; i >= 0; i--) {
			suffix[i] += suffix[i + 1];
		}
		if (suffix[0] < s) {
			puts("-1");
			goto WAorTLE;
		}
		pre1[0] = -1;
		for (int i = 0; i < n; i++) {
			pre1[prefix[i]] = min(pre1[prefix[i]], i);
			suf1[suffix[i]] = max(suf1[suffix[i]], i);
		}
		int ans;
		ans = INF;
		for (int i = 0; i <= suffix[0] - s; i++) {
			ans = min(ans, (pre1[i] + 1) + (n - suf1[suffix[0] - s - i] - 1));
		}
		printf("%d\n", ans);
		WAorTLE:;
	}
	return 0;
}

再见!

posted @ 2022-06-30 14:35  A-Problem-Solver  阅读(67)  评论(0编辑  收藏  举报