CF 1611 BF

B

题面大意

a 个 1,b 个 2,组(1, 1, 1, 2)(1, 1, 2, 2)(1, 2, 2, 2)的组最多能组几组。

题面关键

解题思路

其实我也不知道为什么,但是 $ \min { a, b, \frac{a + b}{4} } $ 就行了。

思路要点

AC 代码

// Problem: B. Team Composition: Programmers and Mathematicians
// Contest: Codeforces - Codeforces Round #756 (Div. 3)
// URL: https://codeforces.com/contest/1611/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int a, b;
		scanf("%d %d", &a, &b);
		printf("%d\n", min(min(a, b), (a + b) / 4));
	}
	return 0;
}

F

题面大意

找一个最长的子串 $ a_l, a_{l + 1}, \cdots, a_{r} $ 使得 $ \sum _ {i = l} ^ {r} a_i + S \geq 0 $ 。

题面关键

既然是一个子串,那能不能双指针?

解题思路

先找第一个符合条件的,如果没有就是 -1 。
然后双指针,每次 l + 1 ,最大限度扩展 r ,然后更新。

思路要点

十年OI一场空,不开ll见祖宗!

AC 代码

// Problem: F. ATM and Students
// Contest: Codeforces - Codeforces Round #756 (Div. 3)
// URL: https://codeforces.com/contest/1611/problem/F
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

int a[200005];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, s;
		scanf("%d %d", &n, &s);
		for (int i = 0; i < n; i++) {
			scanf("%d", &a[i]);
		}
		int r = -1;
		for (int i = 0; i < n; i++) {
			if (s + a[i] >= 0) {
				r = i;
				break;
			}
		}
		if (r == -1) {
			puts("-1");
			continue;
		}
		long long sum = s + a[r];
		int ansl = r, ansr = r, mx = 1;
		for (int l = r; l < n; l++) {
			if (r < l) {
				r++;
				sum += a[r];
			}
			while (r < n && sum >= 0) {
				sum += a[++r];
			}
			sum -= a[r--];
			if (r - l + 1 > mx) {
				ansl = l;
				ansr = r;
				mx = r - l + 1;
			}
			sum -= a[l];
		}
		printf("%d %d\n", ansl + 1, ansr + 1);
	}
	return 0;
}
posted @ 2023-01-14 18:28  A-Problem-Solver  阅读(16)  评论(0编辑  收藏  举报