Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)

A

显然,不管怎么加减,得到的 \(a, b\) 之差的奇偶性不变,所以如果 \(c - d \not\equiv 0 \pmod 2\),无解;如果 \(c = d = 0\),不用操作;否则,将 \(c, d\) 通过一次操作变成奇偶性相等的数后同时减去这个数即可。

代码:

#include <stdio.h>

int main(){
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++){
		int c, d;
		scanf("%d %d", &c, &d);
		if ((c - d) % 2 != 0){
			printf("-1\n");
		} else if (c == 0 && d == 0){
			printf("0\n");
		} else {
			printf("%d\n", (c == d ? 0 : 1) + 1);
		}
	}
	return 0;
}

B

显然,如果奇数和偶数的出现次数之差的绝对值 \(> 1\),无解。

否则考虑奇数还是偶数当头。

如果奇数的出现次数 \(\leq\) 和偶数的出现次数,可以将其搞成偶奇偶奇……的数列,奇数的出现次数 \(\geq\) 和偶数的出现次数时与之基本相同。

取可能存在的情况的最小值即可。

代码:

#include <stdio.h>
#include <stdlib.h>

int a[100007];

inline int min(int a, int b){
	return a < b ? a : b;
}

int main(){
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++){
		int n, cnta = 0, cntb = 0;
		scanf("%d", &n);
		for (int j = 1; j <= n; j++){
			scanf("%d", &a[j]);
			a[j] %= 2;
			if (a[j] == 0){
				cnta++;
			} else {
				cntb++;
			}
		}
		if (abs(cnta - cntb) > 1){
			printf("-1\n");
		} else {
			int ansa = 0x7fffffff, ansb = 0x7fffffff;
			if (cnta <= cntb){
				ansa = 0;
				for (int j = 1, k = 0; j <= n; j++){
					if (a[j] == 1){
						ansa += abs(k * 2 - j + 1);
						k++;
					}
				}
			}
			if (cnta >= cntb){
				ansb = 0;
				for (int j = 1, k = 0; j <= n; j++){
					if (a[j] == 0){
						ansb += abs(k * 2 - j + 1);
						k++;
					}
				}
			}
			printf("%d\n", min(ansa, ansb));
		}
	}
	return 0;
}

C

时隔多年,来把这道题补了。

考虑枚举一个左端点 \(l \bmod 2 = 1\),再从左到右遍历右端点 \(r \bmod 2 = 0\),钦定 \((l, r)\) 中所有括号必选,\(l, r\) 处的括号各至少选一个。

把左括号看做 \(1\)、右括号看做 \(-1\),则记录括号序列区间和和前缀 \(\min\),解个不等式即可。时间复杂度为 \(O(n^2)\)

代码:

#include <stdio.h>

typedef long long ll;

int c[1007];

inline ll max(ll a, ll b){
	return a > b ? a : b;
}

inline ll min(ll a, ll b){
	return a < b ? a : b;
}

int main(){
	int n;
	ll ans = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++){
		scanf("%d", &c[i]);
	}
	for (int i = 1; i < n; i += 2){
		ll sum = 0, min_val = 0;
		for (int j = i + 1; j <= n; j++){
			if (j % 2 == 0){
				ll l = max(max(-min_val, 1), 1 - sum), r = min(c[i], c[j] - sum);
				if (l <= r) ans += r - l + 1;
				sum -= c[j];
				if (min_val > sum) min_val = sum;
			} else {
				sum += c[j];
			}
		}
	}
	printf("%lld", ans);
	return 0;
}
posted @ 2021-08-30 14:31  LovelyLeasier  阅读(38)  评论(0)    收藏  举报