Codeforces Round #418 (Div. 2)

A

用b数组中的数去代替a数组中0的数,保证数组a和数组b之间以及内部之间数都是不相同的,问你是否可以使得序列不递增

很显然k>=2的话就一定能不递增,k为1的情况特别判断就好

#include <bits/stdc++.h>

using namespace std;
#define LL long long
#define pb push_back
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 100 + 10;
int n, 	k;
int a[qq], b[qq];

int main(){
	scanf("%d%d", &n, &k);
	int cnt = 0;
	int snt = 0;
	REP(i, 1, n){
		scanf("%d", a + i);
	}
	REP(i, 1, k){
		scanf("%d", b + i);
	}
	bool f = false;
	if(k > 1){
		puts("Yes");
		return 0;
	}
	REP(i, 1, n){
		if(a[i] == 0)	a[i] = b[1];
	}
	REP(i, 2, n){
		if(a[i] < a[i - 1])	f = true;
	}
	if(f)	puts("Yes");
	else	puts("No");
	return 0;
}


B

题意:给出两个序列,master心目中有一个序列,他心目中的序列和这两个序列有且只有一个地方不同,也就是说他心目中的序列和a数组只有一个地方不一样,b数组同理,现在让你求出他心目中的数组

思路:可以发现至少有n - 2个位置a数组和b数组的数是相同的,剩下的情况特判就行

#include <bits/stdc++.h>

using namespace std;
#define LL long long
#define pb push_back
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 2e3 + 10;
int a[qq], b[qq];
bool vis[qq];
int num[qq];
int p[4], u[5];

int main(){
	int n;	scanf("%d", &n);
	REP(i, 1, n){
		scanf("%d", a + i);
	}
	REP(i, 1, n){
		scanf("%d", b + i);
	}
	int cnt = 0;
	REP(i, 1, n){
		if(a[i] == b[i])	vis[a[i]] = 1, num[i] = a[i];
		else	p[cnt++] = i;
	}
	int t1, t2;
	int k = 0;
	REP(i, 1, n){
		if(!vis[i])	u[k++] = i;
	}
	if(k == 1){
		num[p[0]] = u[0];
	}else{
		int c1, c2;
		c1 = c2 = 0;
		if(u[0] != a[p[0]])	c1++;
		if(u[0] != b[p[0]])	c2++;
		if(u[1] != a[p[1]])	c1++;
		if(u[1] != b[p[1]])	c2++;
		if(c1 == 1 && c2 == 1)	num[p[0]] = u[0], num[p[1]] = u[1];
		else	num[p[0]] = u[1], num[p[1]] = u[0];
	}
	REP(i, 1, n){
		printf("%d ", num[i]);
	}
	puts("");
	return 0;
}


C

题意:给出一个小写字母的序列,q次询问,每次给你一个mi,一个字母ci, 在序列中可以改变m次使得连续的ci最多,求出来

思路:最开始是n*q*logn卡着边界过了,后来看到大佬们26n^2 + q的算法学习了,ans[i][j]代表字母i,可以修改j次能达到的最大连续数

#include <cstdio>
#include <algorithm>
#define maxn 2017
using namespace std;
int sum[30][1505];
int ans[30][1505];
char st[1505];
int n, q;
int main(){
	scanf("%d", &n);
	scanf("%s", st + 1);
	for(int i = 1; i <= n; ++i){
		sum[st[i] - 'a'][i] = 1;
	}
	for(int i = 0; i < 26; ++i){
		for(int j = 1; j <= n; ++j)
			sum[i][j] += sum[i][j - 1];
	}
	for(int i = 1; i <= n; ++i){
		for(int j = i; j <= n; ++j){
			for(int k = 0; k < 26; ++k){
				int t = sum[k][j] - sum[k][i - 1];
				int p = j - i + 1;
				ans[k][p - t] = max(ans[k][p - t], p);
			}
		}
	}
	for(int i = 0; i < 26; ++i){
		for(int j = 1; j <= n; ++j){
			ans[i][j] = max(ans[i][j], ans[i][j - 1]);
		}
	}
	scanf("%d", &q);
	while(q--){
		int m;	char op[5];
		scanf("%d %s", &m, op);
		int ch = op[0] - 'a';
		printf("%d\n", ans[ch][m]);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值