把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

Codeforces Round #699 (Div. 2)

CF1481A
照题意模拟即可。判一下有没有不够的情况。
code:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int t,n,m,k,x,y,z,now1,now2,now3,now4,flag;
char s[1000036];
int main(){
	register int i;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&x,&y);now1=now2=now3=now4=0;
		scanf("%s",s+1);k=strlen(s+1);
		for(i=1;i<=k;i++){
			if(s[i]=='U') now1++;
			else if(s[i]=='D') now2++;
			else if(s[i]=='R') now3++;
			else now4++;
		}
		if((y>0&&now1<y)||(y<0&&now2<-y)||(x>0&&now3<x)||(x<0&&now4<-x))printf("NO\n"); 
		else printf("YES\n");
	}
}

CF1481B
注意到\(k\)很大,而\(h_i\)很小,所以一定最多只会有\(10^4\)块石头落在界内,其他一定在界外。对于这个\(10^4\)块暴力判即可。
code:

#include<cstdio>
using namespace std;
int n,m,x,y,z,a[100039],flag,t, k,ans; 
int main(){
//	freopen("1.in","r",stdin);
	register int i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);flag=0;
		for(i=1;i<=n;i++) scanf("%d",&a[i]);
		while(1){
		    for(i=1;i<n;i++) if(a[i]<a[i+1]){a[i]++;k--;break;}
			if(i==n) break;
			if(!k){flag=1;printf("%d\n",i);break;}
		}
		if(!flag) printf("-1\n");
	}
}

CF1481C
把画家从后往前做。
如果有一块没有被涂到相应颜色而这个画家又恰好是这个颜色的,就让他涂这个颜色。
如果有一个画家没地方涂,那么可以让他涂三种地方:
在他后面的人涂的,原来是这个颜色,目标也是这个颜色的地方。以及同色的人涂好的地方。
考虑这几种情况就好了。
code:

#include<cstdio>
#include<vector>
using namespace std;
int t,n,m,k,x,y,z,a[100039],b[100039],c[100039],ans[100039],h[100039],flag,now,he[100039];
vector<int> g[100039];
int main(){
	register int i;
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d",&t);
	while(t--){
		for(i=1;i<=n;i++) g[i].clear(),h[i]=0,ans[i]=0,he[i]=0;now=0;flag=0;
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++) scanf("%d",&a[i]);
		for(i=1;i<=n;i++) scanf("%d",&b[i]);
		for(i=1;i<=m;i++) scanf("%d",&c[i]);
		for(i=1;i<=n;i++) if(a[i]!=b[i]) g[b[i]].push_back(i),h[b[i]]++;
		for(i=1;i<=n;i++) if(a[i]==b[i]) he[a[i]]=i;
		for(i=m;i;i--){
			if(h[c[i]]) ans[i]=g[c[i]][--h[c[i]]],now=ans[i];
			else {
				if(!g[c[i]].size()){
					if(!now&&!he[c[i]]){flag=1;break;}
					else ans[i]=now?now:(he[c[i]],now=he[c[i]]);
				}
				else ans[i]=g[c[i]][0];
			}
		}
		for(i=1;i<=n;i++) if(h[i]) flag=1;
		if(flag) printf("NO\n");
		else {
			printf("YES\n");
			for(i=1;i<=m;i++) printf("%d ",ans[i]);printf("\n");
		} 
	}
}

CF1481D
如果有两条边互为反向边且同色就一定可行。
接下来分类讨论:
如果\(m\)是奇数一定可行,可以沿不同色环走下去。
如果\(m\)是偶数就对于每个点找到一条入边和一条同色的出边即可。这样就能构成一个环。
对于输出方案那么就着上面的情况再讨论一下\(m\)是否为\(4\)的倍数即可。
code:

#include<cstdio>
#include<vector>
using namespace std;
int n,m,k,x,y,z,t,f[1039][1039],g[1039][1039],flag,now1,now2;
char _s;
int main(){
	//freopen("1.in","r",stdin);
	register int i,j,h;
	scanf("%d",&t);
	while(t--){
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++) g[i][j]=0;
		}flag=0;
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				_s=getchar();
				while(_s!='a'&&_s!='b'&&_s!='*') _s=getchar();
				if(_s=='a') g[i][j]=1;
				if(_s=='b') g[i][j]=-1;
			}
		}
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++) {
				if(i==j) continue;
				if(g[i][j]==g[j][i]){
				    flag=1;printf("YES\n");
			    	for(h=1;h<=m+1;h++)printf("%d ",(h&1)?i:j);
			    	break;
		    	}
			}   
			if(flag) break;
		}
		if(!flag){
			if(m&1) {
				printf("YES\n");
				for(i=1;i<=m+1;i++)printf("%d ",(i&1)?1:2);
			}
			else{
				for(i=1;i<=n;i++){
					now1=0;now2=0;
					for(j=1;j<=n;j++){
						if(i!=j){
							if(g[i][j]==1) now1=j;
							if(g[i][j]==-1) now2=j;
						}
					} 
					if(now1&&now2){
						flag=1;printf("YES\n");
						if(m%4==2){
							printf("%d ",now2);
							for(j=1;j<=m/2;j++)printf("%d %d ",i,(j&1)?now1:now2); 
						} 
						else{
							printf("%d ",i);
							for(j=1;j<=m/4;j++)printf("%d %d %d %d ",now1,i,now2,i);
						}
						break;
					}
				}
				if(!flag) printf("NO");
			}
		}
		printf("\n");
	}
}

CF1481E
这个东西正着不太好做,考虑倒着来。找到不用移动的最大值。
\(dp_i\)\([i,n]\)这一区间不用移动的最大值,因为是放到最后面所以倒着来。
如果\(i\)是某个区间左端点直接转移即可。
但是如果不是那么记录前缀最大颜色个数,与\(dp_{i+1}\)取min。这个东西你会发现一定可以构造出一种方案使得这些颜色不会移动。
时间复杂度\(O(n)\)
code:

#include<cstdio>
#include<vector>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,k,x,y,z,dp[500039],l[500039],r[500039],now,a[500039],siz[500039],g[500039],f[500039];
int main(){
///	freopen("1.in","r",stdin);
	register int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&a[i]),siz[a[i]]++,l[a[i]]=l[a[i]]?l[a[i]]:i,r[a[i]]=i;
	for(i=1;i<=n;i++) if(l[i]) g[l[i]]=i;
	for(i=n;i;i--){
		dp[i]=dp[i+1];f[a[i]]++;
		if(g[i]) dp[i]=max(dp[i],dp[r[g[i]]+1]+siz[g[i]]);
		else dp[i]=max(dp[i],f[a[i]]);
	}
	printf("%d\n",n-dp[1]);
}

CF1481F
咕咕咕

posted @ 2021-02-06 09:08  275307894a  阅读(227)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end