zoukankan      html  css  js  c++  java
  • Codeforces Round #533 (Div. 2)比赛总结

    在第一次CF第一题被叉与第二次CF第一题被FST掉的阴影下,报名参加了第三次的CF。。。心路历程大概是这样的:

    开场后15min内:wocCF怎么上不上去?。。。算了到CF群里开始看起了T1题面,慌乱之中又看漏了T1中的正整数,成功掉了50分。。。

    终于在21min过了T1,开始看T2

    1min后:嗯这道题怎么好像很简单啊。。。4min左右写完,然后网卡,交不了。。。

    然后大概在26min左右看起了T3:这道题不是傻逼DP吗?写完把细节改了改,35min左右过了所有样例,然而。。。woc怎么还是交不了?

    于是看起T4。。。到了41min,啊终于能交了,于是在41min同时过了T2与T3

    剩下的2h-41min=1h19min:一直T4BFS不会写,非要写BFS套BFS还傻逼地以为写的非常是正解,看到TLE后还加了一个类似分层图的优化更加觉得是正解了,但这并不妨碍我从头T到尾。。。

    然后、、比赛结束,以rank1300多强势垫底


    认真地总结一下吧:CF每次都发挥不出水平,主要是因为CF的按时间减分的赛制让我每次都非常紧张,迫切地想把每一题都迅速做完,然后每题就不敢多想,自然也就不能发挥出来了。所以既然考场上没来得及想,就在考完试后再多想想吧。其次的话,自己水平还是不行吧,如果水平够的话也不会那么紧张,所以还是需要多加训练。话不多说,开始说题


    A. Salem and Sticks

    暴力枚举,三种情况取个min即可

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    const int N=1e3+10;
    const int INF=1e9;
    int n,a[N],t,ans=INF;
    int main(){
    	scanf("%d",&n);
    	for(register int i=1;i<=n;i++)scanf("%d",&a[i]);
    	for(register int p=1;p<=100;p++){
    		int sum=0;
    		for(register int i=1;i<=n;i++)
    			sum+=min(abs(a[i]-p),min(abs(a[i]-1-p),abs(a[i]+1-p)));
    		if(sum<ans)ans=sum,t=p;
    	}
    	printf("%d %d
    ",t,ans);
    	return 0;
    }
    

    B. Zuhair and Strings

    还是暴力枚举

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=2e5+10;
    int n,k,sum,ans,now;
    char s[N];
    int main(){
    	scanf("%d%d",&n,&k);
    	scanf("%s",s+1);
    	for(register int i=0;i<26;i++){
    		sum=now=0;
    		for(register int j=1;j<=n;j++){
    			if(s[j]==i+'a')now++;else now=0;
    			if(now==k)sum++,now=0;
    		}
    		ans=max(ans,sum);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    C. Ayoub and Lost Array

    (dp[i][j])表示前 (i) 个数和在模 (3) 意义下为 (j) 的方案数,然后枚举 (l,r) 转移,复杂度 (O(3n(r-l)))

    考虑把 (l-r) 中的数放在模 (3) 的剩余系下处理,这样复杂度就只有 (O(9n))

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=2e5+10;
    const int mod=1e9+7;
    int n,l,r,dp[N][3],num[3];
    inline void Add(int &x,int y){x+=y;x-=x>=mod? mod:0;}
    int main(){
    	scanf("%d%d%d",&n,&l,&r);
    	num[0]=r/3+1;
    	if(r-1>=0)num[1]=(r-1)/3+1;
    	if(r-2>=0)num[2]=(r-2)/3+1;
    	if(l-1>=0)num[0]-=max((l-1)/3+1,0);
    	if(l-2>=0)num[1]-=max((l-2)/3+1,0);
    	if(l-3>=0)num[2]-=max((l-3)/3+1,0);
    	dp[0][0]=1;
    	for(register int i=1;i<=n;i++)
    		for(register int j=0;j<3;j++)
    			for(register int p=0;p<3;p++)
    				Add(dp[i][j],1ll*dp[i-1][(j-p+3)%3]*num[p]%mod);
    	printf("%d
    ",dp[n][0]);
    	return 0;
    }
    

    D. Kilani and the Game

    也就是个简单的BFS,注意访问过的点直接打上vis标记不再访问即可

    同一种颜色的点同时BFS,不要每个单独BFS(我当时就是这样T掉的)

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=1e3+10;
    const int M=20;
    int n,m,p,s[N],head[M],cnt,num[N][N],ans[M];
    int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    bool vis[N][N];
    char mp[N][N];
    struct peo{int nxt,x,y;}P[N*N];
    struct node{int lef,x,y,col;node(int leff=0,int xx=0,int yy=0,int coll=0){lef=leff;x=xx;y=yy;col=coll;}};
    queue<node>q;
    inline void Add(int po,int x,int y){P[++cnt].nxt=head[po];P[cnt].x=x;P[cnt].y=y;head[po]=cnt;}
    inline void exBFS(node k){
    	queue<node>nq;nq.push(k);
    	while(!q.empty()&&q.front().col==k.col)nq.push(q.front()),vis[q.front().x][q.front().y]=true,q.pop();
    	vis[k.x][k.y]=true;
    	while(!nq.empty()){
    		node u=nq.front();nq.pop();
    		for(register int i=0;i<4;i++){
    			int nx=u.x+dx[i],ny=u.y+dy[i];
    			if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]!='#'&&(num[nx][ny]==0||num[nx][ny]==u.col)){
    				num[nx][ny]=u.col;
    				if(!vis[nx][ny]){
    					vis[nx][ny]=true;
    					if(u.lef>1)nq.push(node(u.lef-1,nx,ny,u.col));
    					else q.push(node(s[u.col],nx,ny,u.col));
    				}
    			}
    		}
    	}
    }
    inline void BFS(){
    	while(!q.empty()){node u=q.front();q.pop();exBFS(u);}
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&p);
    	for(register int i=1;i<=p;i++)scanf("%d",&s[i]);
    	for(register int i=1;i<=n;i++)scanf("%s",mp[i]+1);
    	for(register int i=1;i<=n;i++)
    		for(register int j=1;j<=m;j++)
    			if(mp[i][j]!='#'&&mp[i][j]!='.')
    				Add(mp[i][j]-'0',i,j),num[i][j]=mp[i][j]-'0';
    	for(register int i=1;i<=p;i++)
    		for(register int j=head[i];j;j=P[j].nxt)
    			q.push(node(s[i],P[j].x,P[j].y,i)),vis[P[j].x][P[j].y]=true;
    	BFS();
    	for(register int i=1;i<=n;i++)
    		for(register int j=1;j<=m;j++)
    			ans[num[i][j]]++;
    	for(register int i=1;i<=p;i++)
    		printf("%d%c",ans[i],i==p? '
    ':' ');
    	return 0;
    }
    

    E. Helping Hiasat

    因为一个组中的人一定是相互排斥的,所以在一个组中的人中两两建边,表示这两个人不能同时选,然后建出来的图的最大独立集的点数就是最多的愉悦人数。

    那么怎么求无向图的最大独立集呢?有一个性质:一个无向图的最大独立集等于这个无向图补图的最大团。

    这个性质可以这么理解:对于原图,如果两个点之间有边,那么在补图中一定没有这条边,而最大团要求所选取的点集中的点两两都有边相连,那么这两个点就不可能同在补图的最大团中,也就相应的不可能同在原图的最大独立集中了

    然后最大团的话,多随机几下加点顺序取个最大值就行了

    #include<cstdio>
    #include<iostream>
    #include<map>
    #include<cstring>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    const int N=50;
    int n,m,k,store[N],a[N],tot,T=5e4;
    bool Walk[N][N];
    string s;
    map<string,int>mp;
    bitset<N>sav,ans;
    inline void Process1(){
    	for(register int i=1;i<=store[0];i++)
    		for(register int j=i+1;j<=store[0];j++)
    			Walk[store[i]][store[j]]=Walk[store[j]][store[i]]=false;
    	memset(store,0,sizeof(store));
    }
    inline void Process2(){
    	if(!mp.count(s))mp[s]=++tot;
    	store[++store[0]]=mp[s];
    }
    int main(){
    	scanf("%d%d",&n,&m);scanf("%d",&k);n--;
    	memset(Walk,true,sizeof(Walk));
    	while(n--){
    		scanf("%d",&k);
    		if(k==1)Process1();
    		else cin>>s,Process2();
    	}
    	Process1();
    	for(register int i=1;i<=m;i++)a[i]=i;
    	while(T--){
    		random_shuffle(a+1,a+m+1);
    		for(register int i=1;i<=m;i++)sav[i]=1;
    		for(register int i=1;i<=m;i++)
    			if(sav[a[i]]==1)
    				for(register int j=i+1;j<=m;j++)
    					if(!Walk[a[i]][a[j]])sav[a[j]]=0;
    		if(sav.count()>ans.count())ans=sav;
    	}
    	printf("%d
    ",ans.count());
    	return 0;
    }
    

    1月31号的codeforces再战!(立flag:下次一定要到深蓝)

  • 相关阅读:
    [转载]游戏外挂原理
    python cookbook
    RF user guide
    测试理论-selenium的工作原理
    测试理论- the conten of test plan
    测试理论--branch testing and boundary testing
    测试理论--向高级出发
    fiddler安装及配置
    python 面试题: 列表表达式
    [redis]如何将redis设置成diango的cache backend
  • 原文地址:https://www.cnblogs.com/ForwardFuture/p/10296662.html
Copyright © 2011-2022 走看看