刷题记录 CF每日一题打卡 2020.5月?-六月16

1.CF1355D Game With Array

给出两个数 N N N, S S S

问是否可以找到一个序列和一个数 K K K( 0 < = K < = S 0<=K<=S 0<=K<=S)满足:存在一个长度为 N N N,和为 S S S序列,在其中找不到一个子段的和为 K K K或者 S − K S-K SK

如果可以,输出YES以及找到的序列还有 K K K,否则,输出NO

首先手玩一下样例自己造几组数据可以发现,如果 2 ∗ n > s 2*n>s 2n>s的话一定是无解的
然后构造一个除了最后一位之外全为1的数列即可

#include<bits/stdc++.h>
using namespace std;
int n,m,s;
const int maxn=1e5+5;
int a[maxn],b[maxn],c[maxn];
int main(){
	cin>>n>>s;
	if(2*n>s){
		puts("NO");
		return 0;
	}
	else{
		puts("YES");
		for(int i=1;i<=n-1;i++){
			cout<<"1"<<" ";
		}
		cout<<s-n+1<<endl;
		cout<<s/2;
	}
	return 0;
}

2.CF1352D Alice, Bob and Candies

一个很屑的模拟

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int tt,n,m,a[maxn],b[maxn],num[maxn];
int main(){
	cin>>tt;
	while(tt--){
		cin>>n;
		int ans1=0,ans2=0,cnt=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		int i=0,j=n+1;
		bool c=false;
		int now1=0,now2=0;
		while(i<j){
			cnt++;
			if(!c){
				now1=0;
				while(1){
					i++;
					now1+=a[i];
					if(now1>now2)break;
				}
				if(i>=j){
					while(i>=j){
						now1-=a[i];
						i--;
					}
					i++;
				}
				ans1+=now1;
			}
			else{
				now2=0;
				while(1){
					j--;
					now2+=a[j];
					if(now2>now1)break;
				}
				if(i>=j){
					while(j<=i){
						now2-=a[j];
						j++;
					}
					j--;
				}
				ans2+=now2;
			}
			c=!c;
			if(i>=j-1)break;
		}
		printf("%d %d %d\n",cnt,ans1,ans2);
	}
	return 0;
}

3.CF1352F Binary String Reconstruction

每组数据有三个整数 n 0 , n 1 , n 2 n_0,n_1,n_2 n0,n1,n2

你需要构造一个 01 01 01 串,长度为 n 0 + n 1 + n 2 + 1 n_0+n_1+n_2+1 n0+n1+n2+1,对于每一个长度为 2 2 2 的连续子串,总共有 n 0 n_0 n0 个和为 0 0 0, 有 n 1 n_1 n1 个和为 1 1 1,有 n 2 n_2 n2 个和为 2 2 2

保证输入有解,对于每一组数据,输出一行,为一个 01 01 01 串,没有空格,如果有多组解,输出任意一个即可。

先输出 a + 1 a+1 a+1个0,再输出 c + 1 c+1 c+1个1,最后输出长度为 b − 1 b-1 b1的01串即可

#include<bits/stdc++.h>
using namespace std;
int t;
int a,b,c;
int main(){
	cin>>t;
	while(t--){
		cin>>a>>b>>c;
		int n=a+b+c+1;
		if(a==0&&b==0){
			for(int i=1;i<=n;i++){
				printf("1");
			}
			cout<<endl;
			continue;
		}
		if(b==0&&c==0){
			for(int i=1;i<=n;i++){
				printf("0");
			}
			cout<<endl;
			continue;
		}
		int ans1,ans2,ans3;
		for(int i=1;i<=a+1;i++){
			printf("0");
		}
		for(int i=1;i<=c+1;i++){
			printf("1");
		}
		for(int i=1;i<=b-1;i++){
			if(i%2==1)printf("0");
			else printf("1");
		}
		cout<<endl;
	}
	return 0;
}

4.CF1352E Special Elements

The first line contains an integer t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1t1000 ) — the number of test cases in the input. Then t t t test cases follow.

Each test case is given in two lines. The first line contains an integer $ n $ ( $ 1 \le n \le 8000 $ ) — the length of the array a a a . The second line contains integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,,an ( 1 ≤ a i ≤ n 1 \le a_i \le n 1ain ).

It is guaranteed that the sum of the values of $ n $ for all test cases in the input does not exceed 8000 8000 8000

给你a数列,让你判断其中的每个元素是否能写成数列中几个连续元素之和,并统计个数。

暴力枚举求后缀和,超过n就break

#include<bits/stdc++.h>
using namespace std;
int t,n,m;
int a[8005],sum[8005];
int dd[8005];
signed main(){
	cin>>t;
	while(t--){
		cin>>n;
		memset(dd,0,sizeof(dd));
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
		}
		for(int i=1;i<=n-1;i++){
			sum[i]=a[i];
			for(int j=i+1;j<=n;j++){
				sum[j]=sum[j-1]+a[j];
				if(sum[j]>n)break;
				dd[sum[j]]=1;
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++){
			if(dd[a[i]]==1)ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}

5.CF1364C Ehab and Prefix MEXs

给出一个长度为 n n n 的序列 A A A,你需要找到一个长度为 n n n 的序列 B B B,满足 A i = m e x ( { B 1 , B 2 , … , B n } ) A_i=mex(\{B_1,B_2,\dots,B_n\}) Ai=mex({B1,B2,,Bn})

其中 m e x mex mex 函数的结果是最小的未出现在集合中的非负整数

如果 i > 1 , a [ i − 1 ] < a [ i ] i>1,a[i-1]<a[i] i>1a[i1]<a[i]就把这个数填上,如样例3,输入为 1 , 1 , 3 1,1,3 113 i = 1 i=1 i=1时候,输出 0 0 0 f = 1 f=1 f=1,i=2,输出 f = 2 f=2 f=2 f + + f++ f++变为 2 2 2,当 i = 3 i=3 i=3 a [ 2 ] < a [ 3 ] a[2]<a[3] a[2]<a[3],此时必须填入 a [ 2 ] a[2] a[2],因为 a [ 2 ] a[2] a[2]是前一组中不存在的最小数字,不填上它的话就不可能让这个 m e x mex mex变成 a [ 3 ] a[3] a[3]

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
const int maxn=1e5+5;
int a[maxn],b[maxn],c[maxn];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		c[a[i]]=1;
	}
	int f=0;
	for(int i=1;i<=n;i++){
		if(i>1&&a[i-1]<a[i]){
			cout<<a[i-1]<<" ";
		}
		else{
			while(c[f]){
				f++;
			}
			cout<<f++<<" ";
		}
	}
	return 0;
}

6.CF1361A Johnny and Contribution

咕了,待补

7.CF1365D Solve The Maze

要封住每一个坏人,问是否所有好人都能到达终点

先将坏人边上的路变成墙,再从终点 d f s dfs dfs看遇到的好人数量是否为总数即可
需要特判终点不可到达并且好人数量不为 0 0 0的情况

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
const int dx[]={1,-1,0,0};
const int dy[]={0,0,-1,1};
char a[55][55];
int mz[55][55];
int vis[55][55];
int ans=0;
int flag=0;
void dfs(int x,int y){
	vis[x][y]=1;
	if(a[x][y]=='G')ans++;
	for(int i=0;i<4;i++){
		int xx=dx[i]+x;
		int yy=dy[i]+y;
		if(vis[xx][yy]==0&&mz[xx][yy]!=1&&xx>=1&&yy>=1&&xx<=n&&yy<=m){
			dfs(xx,yy);
		}
	}
	return;
}
signed main(){
	cin>>t;
	while(t--){
		int kk=0;
		memset(vis,0,sizeof vis);
		memset(mz,0,sizeof mz);
		ans=0;
		cin>>n>>m;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				cin>>a[i][j];
				if(a[i][j]=='#'){
					mz[i][j]=1;
				}
				if(a[i][j]=='G'){
					kk++;
				}
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(a[i][j]=='B'){
					mz[i-1][j]=mz[i+1][j]=mz[i][j+1]=mz[i][j-1]=1;
				}
			}
		}
		if(mz[n][m]==1&&kk!=0){
			printf("NO\n");
			continue;
		}
		dfs(n,m);
		if(ans==kk)printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值