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

Codeforces Round #704 (Div. 2)

CF1492A
按照题意模拟即可。注意ceil会有精度误差。
code:

#include<cstdio>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
long long t,a,b,n,m;
inline long long ceil(long long x,long long y){return x/y+(x%y!=0);}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld%lld%lld",&n,&m,&a,&b);
		printf("%lld\n",min(ceil(n,m)*m,min(ceil(n,a)*a,ceil(n,b)*b))-n);
	}
}

CF1492B
显然把大的放前面一定更优,那就开个桶从大到小扫即可。
code:

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

CF1492C
枚举断点\(x\),从左往右维护\(l\)使得\(l\)是满足最小的能表示\(1\)\(x\)的左端点,\(r\)同理,取最大值即可。
code:

#include<cstdio>
#include<bits/stdc++.h>
using namespace std;
int t,n,m,k,x,y,z,l[200039],r[200039],ans;
char a[200039],b[200039];
int main(){
	register int i;
	scanf("%d%d",&n,&m);scanf("%s",a+1);scanf("%s",b+1);
	r[m+1]=n+1;
	for(i=m;i;i--){
		r[i]=r[i+1]-1;
		while(a[r[i]]!=b[i])
		 r[i]--;
	} 
	l[0]=0;
	for(i=1;i<=m;i++){
		l[i]=l[i-1]+1;
		while(a[l[i]]!=b[i]) l[i]++;
	}
	for(i=1;i<m;i++) ans=max(ans,r[i+1]-l[i]);
	printf("%d\n",ans);
}

CF1492D
手玩一下就可以发现只要一对位置相距\(k\)且A在开始点为\(1\),B在结束点为\(1\),其余都相同即可。
注意特判特殊情况。
code:

#include<bits/stdc++.h>
using namespace std;
int n ,m,k,x,y,z,a[1000039],b[1000039];
int main(){
//	freopen("1.in","r",stdin);
	register int i;
	scanf("%d%d%d",&y,&x,&n);m=x+y;
	if((x<=1&&n)||(n>=m-1&&n)){printf("No\n");return 0;}
	if(!y){
		if(!n){
			printf("Yes\n");
			for(i=1;i<=x;i++) printf("1");printf("\n");
			for(i=1;i<=x;i++) printf("1");
		} 
		else printf("No");return 0;
	} 
	if(!n){
	    printf("Yes\n");
		for(i=1;i<=x;i++) printf("1");
		for(i=1;i<=y;i++) printf("0");printf("\n");
		for(i=1;i<=x;i++) printf("1");
		for(i=1;i<=y;i++) printf("0");return 0;
	}
	x--;
	a[1]=1;a[m-n]=1;x--;
	for(i=2;i<=m;i++){
		if(a[i]) continue;if(!x) break;
		a[i]=1,x--;
	}
	for(i=1;i<=m;i++)b[i]=a[i];
	b[m-n]=0;b[m]=1;
	printf("Yes\n");
	for(i=1;i<=m;i++) printf("%d",a[i]);printf("\n");
	for(i=1;i<=m;i++)printf("%d",b[i]);  
}

CF1492E
这里不是正解是随机化乱搞。
首先我们可以完全随机的随机化,这个可以过system test
后来出题人过来卡掉了完全随机。
这时我们可以去重后再随机。然而你发现这个连pretest都过不去了。
所以我们去重时要加权,若原来有\(2k\)个相同的放入\(2\)个即可。
然而EI又过来卡掉了这个做法。
然后我们发现如果当前已经有不满足为\(2\)的节点那么就必须选这个节点所代表的权值了。这样就能过EI的数据了。
然而EI发现不对劲又反手一组数据卡掉了。
我们发现只有\(n=4\)的时候能卡随机化。那么我们只要正向做一遍,反向做一遍,相当于做\(n=2\)成功率就大得多。
然后就过了。
现在正在求hack
code:

#include<bits/stdc++.h>
#define R(n) rand()*rand()%(n)+1
using namespace std;
int n,m,k,x,y,z,flag[250039],fl,a[250039],c[250039],cnt,ans;
double s;
vector<int> f[250039],g[250039],fs[250039];
int main(){
//	freopen("1.in","r",stdin);
	srand(time(0));
	register int i,j,h;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){
		f[i].push_back(0);
		for(j=1;j<=m;j++) scanf("%d",&x),f[i].push_back(x);
	}
	for(i=1;i<=m;i++){
		for(j=1;j<=n;j++) c[j]=f[j][i];
		sort(c+1,c+n+1);
		g[i].push_back(0);fs[i].push_back(0);
		for(j=1;j<=n;j=h){
			for(h=j;h<=n;h++) if(c[j]!=c[h]) break;
			cnt=h-j;while(cnt>0) g[i].push_back(c[j]),cnt-=R(6);fs[i].push_back(c[j]); 
		}
	}
	while(1){
		if(clock()>500) break;fl=ans=0;
		for(i=1;i<=m;i++){
			x=R(g[i].size()-1);
			if(ans){
				for(j=1;j<=g[i].size();j++) if(g[i][j]==f[ans][i]){x=j;break;}
			}
			for(j=1;j<=n;j++) 
			if(f[j][i]!=g[i][x]) {
				flag[j]++;
				if(flag[j]==2){
					ans=j;
				} 
				if(flag[j]>2){fl=1;break;}
			}
			a[i]=x;
			if(fl) break;
		}
		if(fl){
			for(i=1;i<=n;i++) flag[i]=0;
		}
		else{
			printf("Yes\n");
			for(i=1;i<=m;i++) printf("%d ",g[i][a[i]]);return 0;
		}
	}
	while(1){
		if(clock()>1450) break;fl=ans=0;
		for(i=1;i<=m;i++){
			x=R(fs[i].size()-1);
			if(ans){
				for(j=1;j<=fs[i].size();j++) if(fs[i][j]==f[ans][i]){x=j;break;}
			}
			for(j=1;j<=n;j++) 
			if(f[j][i]!=fs[i][x]) {
				flag[j]++;
				if(flag[j]==2){
					ans=j;
				} 
				if(flag[j]>2){fl=1;break;}
			}
			a[i]=x;
			if(fl) break;
		}
		if(fl){
			for(i=1;i<=n;i++) flag[i]=0;
		}
		else{
			printf("Yes\n");
			for(i=1;i<=m;i++) printf("%d ",fs[i][a[i]]);return 0;
		}
	}
	while(1){
		if(clock()>1950) break;fl=ans=0;
		for(i=m;i;i--){
			x=R(fs[i].size()-1);
			if(ans){
				for(j=1;j<=fs[i].size();j++) if(fs[i][j]==f[ans][i]){x=j;break;}
			}
			for(j=1;j<=n;j++) 
			if(f[j][i]!=fs[i][x]) {
				flag[j]++;
				if(flag[j]==2){
					ans=j;
				} 
				if(flag[j]>2){fl=1;break;}
			}
			a[i]=x;
			if(fl) break;
		}
		if(fl){
			for(i=1;i<=n;i++) flag[i]=0;
		}
		else{
			printf("Yes\n");
			for(i=1;i<=m;i++) printf("%d ",fs[i][a[i]]);return 0;
		}
	}
	printf("No\n");
}
posted @ 2021-02-24 14:17  275307894a  阅读(91)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end