Codeforces Round #821 (Div. 2) A-D2

38 篇文章 0 订阅
19 篇文章 0 订阅

题目链接:https://codeforces.com/contest/1733

A - Consecutive Sum

解题思路:

        每个周期里面找最大的就行了。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int n;
int a[mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int k;
		scanf("%d%d", &n, &k);
		for(int i=1;i<=n;i++)
			scanf("%d", a+i);
		
		ll ans = 0;
		for (int i=1;i<=k;i++) {
			int ma = 0;
			for (int j=i;j<=n;j+=k) {
				ma = max(ma, a[j]);
			}
			ans += ma;
		}
		
		printf("%lld\n", ans);
	}
	
    return 0;
}

B - Rule of League

解题思路:

        必然要有一个是0,因为第一场比赛肯定就有人要输。因此剩下那个数就是要整除的了。然后随便构造一下。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int n;
int a[mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		if (b > c) swap(b, c);
		
		if (b == 0 && c == 0) {
			puts("-1");
		} else if(b == 0) {
			if ((a - 1) % c == 0) {
				int cnt = (a - 1) / c;
				for (int i=2; i <= a; i += c) {
					for (int j=1;j<=c;j++) 
						printf("%d ", i);
				}
				puts("");
			} else
				puts("-1");
		} else
			puts("-1");
	}
	
    return 0;
}

C - Parity Shuffle Sorting

解题思路:

        先把第一个位置和第N个位置弄成一样的,那么接下来就可以用两种中的一种使得i位置的值与第一位或者第N位一样了,因此次数不超过N-1。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int n;
int a[mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		for (int i=1;i<=n;i++)
			scanf("%d", a+i);
		if (n == 1) {
			puts("0");
			continue;
		}
		printf("%d\n1 %d\n", n - 1, n);
		if ((a[1] + a[n]) % 2 == 0)
			a[1] = a[n];
		for (int i=2; i<n; i++) {
			if ((a[1] + a[i]) % 2 == 0)
				printf("%d %d\n", i, n);
			else
				printf("1 %d\n", i);
		}
		
	}
	
    return 0;
}

D1 - Zero-One (Easy Version)

解题思路:

        当a序列和b序列不同的位数是奇数时,那么肯定是误解的。因此实际我们只需要观察a、b相同位置上不同的值就行了。一般情况下值需要操作x/2次,x就是不同值的个数,因为x>=y,因此尽量不要让相邻的两位数进行异或就行了,所以当x == 2时,需要特判一下,可能2次y的操作要小于x。因为a ^ c,  b ^ c也能得到a ^ b的效果。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 1e4 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int n;
char s1[mx], s2[mx]; 
vector <int> vec;

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, x, y;
		scanf("%d%d%d", &n, &x, &y);
		scanf("%s", s1 + 1);
		scanf("%s", s2 + 1);
		vec.clear();
		for (int i=1;i<=n;i++) {
			if (s1[i] != s2[i])
				vec.push_back(i);
		}
		if (vec.size() & 1)
			puts("-1");
		else if (vec.size() == 2){
			if (vec[0] + 1 == vec[1]) {
				if (2 * y < x)
					printf("%d\n", 2 * y);
				else
					printf("%d\n", x);
			} else
				printf("%d\n", y);
		} else {
			printf("%lld\n", 1ll * y * vec.size() / 2);
		}
		
	}
	
    return 0;
}

D2 - Zero-One (Hard Version)

解题思路:

        D1中已经讨论了x>=y的情况,那么实际在D2中只需要考虑x < y的情况即可。此时,两个位置i,j需要同时操作,他们的花费可以是(j - i) * x,也可以是y。当j - i == 1时,前者花费肯定更小。假设只有(j - i) * x的情况,那么就很简单了,只要从头开始,对[1,2]、[3,4]、[k-1, k],按顺序对每一对进行计算就行了。但是如果引入了y操作,就增加了一种情况,假设[i, j]是进行y操作的,那么在区间[i+1, j-1]之间肯定没有y操作, 因为如果有,那么可以把[i,j]区间划分为更小的y操作,(a,b)、(c,d)可以变成(a,c)、(d、b)。a < c < d < b。知道了这个条件就没有对j去枚举i,i < j,就有

        dp[j] = min(dp[j], dp[i-1] + y + sec[i+1][j-1]),sec[i][j]为区间[i,j]只使用x的花费,这个可以直接贪心计算。

        dp[j] = min(dp[j], dp[i-1] + dis(i,j) * x+ sec[i+1][j-1])

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 5e3 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int n;
char s1[mx], s2[mx]; 
vector <int> vec;
ll sec[mx][mx];
ll dp[mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, x, y;
		scanf("%d%d%d", &n, &x, &y);
		scanf("%s", s1 + 1);
		scanf("%s", s2 + 1);
		vec.clear();
		for (int i=1;i<=n;i++) {
			if (s1[i] != s2[i])
				vec.push_back(i);
		}
		if (vec.size() & 1)
			puts("-1");
		else if (x >= y) {
			if (vec.size() == 2) {
				if (vec[0] + 1 == vec[1]) {
					if (2 * y < x)
						printf("%d\n", 2 * y);
					else
						printf("%d\n", x);
				} else
					printf("%d\n", y);
			} else {
				printf("%lld\n", 1ll * y * vec.size() / 2);
			}
		} else {
			for (int i=1; i<=vec.size(); i++) {
				for (int j=i+1; j<=vec.size(); j+=2) {
					sec[i][j] = 1e16; 
					int dis = vec[j-1] - vec[j - 2];
					sec[i][j] = min(sec[i][j], sec[i][j-2] + 1ll * dis * x);
				}
			}
			for (int i=2; i <= vec.size(); i+=2) {
				dp[i] = 1e16;
				for (int j=1; j < i; j+=2) {
					dp[i] = min(dp[i], dp[j-1] + y + sec[j+1][i-1]);
					int dis = vec[i-1] - vec[j-1];
					dp[i] = min(dp[i], dp[j-1] + 1ll * dis * x + sec[j+1][i-1]);
				}
			}
			printf("%lld\n", dp[vec.size()]);
		}
		
	}
	
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值