• 【简要题解】Educational Codeforces Round 123 简要题解


    【简要题解】Educational Codeforces Round 123 简要题解

    老年选手打着玩。

    Doors and Keys

    有一个长度为6的串,由rgbRGB各出现一次组成。小写代表钥匙,大写代表门,问你是否可以走到6

    直接模拟就好,然而我tmd看错题了写了个搜索还在想现在CF educational round的第一题怎么这么难了。

    #include<bits/stdc++.h>
    using namespace std;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    char s[15];
    int flg;
    
    void dfs(int l,int r,int dep,int R,int G,int B){
    	//fprintf(stderr,"%d %d %d %d %d %d\n",l,r,dep,R,G,B);
    	if(R<0||G<0||B<0) return;
    	if(l==1&&r==6) return flg=1,void();
    	if(dep>15||flg) return;
    	while(islower(s[r+1])){
    		R+=s[r+1]=='r';
    		G+=s[r+1]=='g';
    		B+=s[r+1]=='b';
    		++r;
    	}
    	while(islower(s[l-1])){
    		R+=s[l-1]=='r';
    		G+=s[l-1]=='g';
    		B+=s[l-1]=='b';
    		--l;
    	}
    	if(isupper(s[l-1])) dfs(l-1,r,dep+1,R-(s[l-1]=='R'),G-(s[l-1]=='G'),B-(s[l-1]=='B'));
    	if(isupper(s[r+1])) dfs(l,r+1,dep+1,R-(s[r+1]=='R'),G-(s[r+1]=='G'),B-(s[r+1]=='B'));
    }
    
    int main(){
    	int T=qr();
    	while(T--){
    		flg=0;
    		scanf("%s",s+1);
    		for(int t=1;t<=1;++t)
    			if(islower(s[t]))
    				dfs(t,t,0,s[t]=='r',s[t]=='g',s[t]=='b');
    		if(flg) puts("YES");
    		else puts("NO");
    	}
    	return 0;
    }
    

    Anti-Fibonacci Permutation

    一个排列是反斐波那契的,当且仅当\(\forall i \ge 3,p_{i-1}+p_{i-2}\not = p_i\),对于一个\(n\),请你输出\(n\)个反斐波那契排列

    排列小于\(10\)先搜索一下然后打表。

    排列大于\(10\)考虑把\(1\quad 2\quad 3\)换成\(3\quad 1 \quad 2\),然后对于排列最后\(5\)个数进行next_permutation,一定可以搞出很多出来,选出其中\(n\)个即可,复杂度\(O(5!n)\)

    #include<bits/stdc++.h>
    using namespace std;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    
    const int maxn=150;
    int a[maxn];
    string ans[]={"","","","1 3 2 \n2 3 1 \n3 1 2 \n","1 2 4 3 \n1 3 2 4 \n1 4 2 3 \n1 4 3 2 \n","1 2 4 3 5 \n1 2 4 5 3 \n1 2 5 3 4 \n1 2 5 4 3 \n1 3 2 4 5 \n","1 2 4 3 5 6 \n1 2 4 3 6 5 \n1 2 4 5 3 6 \n1 2 4 5 6 3 \n1 2 5 3 4 6 \n1 2 5 3 6 4 \n","1 2 4 3 5 6 7 \n1 2 4 3 5 7 6 \n1 2 4 3 6 5 7 \n1 2 4 3 6 7 5 \n1 2 4 5 3 6 7 \n1 2 4 5 3 7 6 \n1 2 4 5 6 3 7 \n","1 2 4 3 5 6 7 8 \n1 2 4 3 5 6 8 7 \n1 2 4 3 5 7 6 8 \n1 2 4 3 5 7 8 6 \n1 2 4 3 6 5 7 8 \n1 2 4 3 6 5 8 7 \n1 2 4 3 6 7 5 8 \n1 2 4 3 6 7 8 5 \n","1 2 4 3 5 6 7 8 9 \n1 2 4 3 5 6 7 9 8 \n1 2 4 3 5 6 8 7 9 \n1 2 4 3 5 6 8 9 7 \n1 2 4 3 5 6 9 7 8 \n1 2 4 3 5 6 9 8 7 \n1 2 4 3 5 7 6 8 9 \n1 2 4 3 5 7 6 9 8 \n1 2 4 3 5 7 8 6 9 \n","1 2 4 3 5 6 7 8 9 10 \n1 2 4 3 5 6 7 8 10 9 \n1 2 4 3 5 6 7 9 8 10 \n1 2 4 3 5 6 7 9 10 8 \n1 2 4 3 5 6 7 10 8 9 \n1 2 4 3 5 6 7 10 9 8 \n1 2 4 3 5 6 8 7 9 10 \n1 2 4 3 5 6 8 7 10 9 \n1 2 4 3 5 6 8 9 7 10 \n1 2 4 3 5 6 8 9 10 7 \n"};
    
    int main(){
    	int T=qr();
    	while(T--){
    		int n=qr();
    		if(n<=10) printf("%s",ans[n].c_str());
    		else{
    			for(int t=1;t<=n;++t) a[t]=t;
    			a[1]=3; a[2]=1; a[3]=2;
    			int cnt=0;
    			do{
    				int flg=1;
    				for(int t=3;t<=n;++t)
    					if(a[t-2]+a[t-1]==a[t])
    						flg=0,t=n;
    				if(flg){
    					++cnt;
    					for(int t=1;t<=n;++t)
    						printf("%d ",a[t]);
    					putchar('\n');
    				}
    			}while(next_permutation(a+n-5+1,a+n+1)&&cnt<n);
    			if(cnt!=n){
    				//cerr<<"qwq";
    				return 0;
    			}
    		}
    	}
    	return 0;
    }
    

    Increase Subarray Sums

    给定一个序列和一个数\(x\),设\(f(k)\)表示选取序列中\(k\)个数加上\(x\)然后求出的最大子段和。输出\(f(0)\dots f(n)\)

    \(Max[i]\)表示长度为\(i\)的子段中的最大子段和,然后\(f(k)=\max(Max[i]+\min(i,k)\times x)\),复杂度\(O(n^2)\)

    #include<bits/stdc++.h>
    using namespace std;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    typedef long long ll;
    const int maxn=5005;
    int a[maxn];
    ll Max[maxn];
    
    int main(){
    	int T=qr();
    	while(T--){
    		ll n=qr(),x=qr();
    		for(int t=1;t<=n;++t) a[t]=qr();
    		for(int t=1;t<=n;++t) Max[t]=-1e12;
    		for(int t=1;t<=n;++t){
    			int s=0;
    			for(int i=t;i<=n;++i){
    				s+=a[i];
    				Max[i-t+1]=max<ll>(Max[i-t+1],s);
    			}
    		}
    		for(int k=0;k<=n;++k){
    			ll ans=0;
    			for(int i=0;i<=n;++i)
    				ans=max<ll>(ans,min(k,i)*x+Max[i]);
    			printf("%lld ",ans);
    		}
    		putchar('\n');
    	}
    	return 0;
    }
     
    

    Cross Coloring

    有一个\(n\times m\)的格子图,初始是白色。你要进行\(q\)次操作,每次操作你要选择\(k\)种(k种都不是白色)颜色中一个颜色,然后\(x_i\)行和\(y_i\)列就被染上这个颜色。问染色方案数。

    答案\(=\)(在最终染色方案中有用的染色操作)\(^k\)

    考虑一个操作\(i\)是没用的(即被其他染色操作完全覆盖了),当且仅当

    • 对于某个行,\(j>i,x_j=x_i\) 或者 在之后所有列都被染过一次颜色。

    • 对于某个列,\(j>i,y_j=y_i\) 或者 在之后所有行都被染过一次颜色了。

    复杂度\(O(n)\)

    #include<bits/stdc++.h>
    using namespace std;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    const int maxn=2e5+5;
    const int mod=998244353;
    typedef long long ll;
    
    int ksm(const int&ba,const int&p){
    	int ret=1;
    	for(int t=p,b=ba;t;t>>=1,b=1ll*b*b%mod)
    		if(t&1) ret=1ll*ret*b%mod;
    	return ret;
    }
    int row[maxn],col[maxn];
    pair<int,int> que[maxn];
    
    int main(){
    	int T=qr();
    	while(T--){
    		int n=qr(),m=qr(),k=qr(),Q=qr(),fcnt=Q,cntr=0,cntc=0;
    		for(int t=1;t<=n;++t) row[t]=0;
    		for(int t=1;t<=m;++t) col[t]=0;
    		for(int t=1;t<=Q;++t) que[t].first=qr(),que[t].second=qr();
    		for(int t=Q;t;--t){
    			int cnt=0;
    			if(row[que[t].first]||cntc==m) ++cnt;
    			if(!row[que[t].first]) row[que[t].first]=t,++cntr;
     			if(col[que[t].second]||cntr==n) ++cnt;
    			if(!col[que[t].second]) col[que[t].second]=t,++cntc;
    			if(cnt==2) --fcnt;
    		}
    		int ans=ksm(k,fcnt);
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    

    Expand the Path

    有一个机器人,遵循DR规则,即遇到一个D就往下走一格,遇到一个R就往右走一格。现在初始给你一个DR串,你每次可以选择任何一个字母,比如D,把他变成DD。问你可以经过多少格?一个格子可以被经过,当且仅当存在一种操作该DR串的方式,使得机器人在不走出地图的情况下经过这个格子。

    考虑那些走不到的格子,是原DR串走出的轮廓线下方或者右方,模拟一下即可。(有事待会再详细更博,未完待续)

    #include<bits/stdc++.h>
    using namespace std;
    int qr(){
    	int ret=0,c=getchar(),f=0;
    	while(!isdigit(c)) f=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    typedef long long ll;
    const int maxn=2e5+5;
    char s[maxn];
    
    int main(){
    	int T=qr();
    	while(T--){
    		int n=qr();
    		scanf("%s",s+1);
    		int L=strlen(s+1);
    		int flg=1;
    		for(int t=2;t<=L;++t)
    			if(s[t]!=s[t-1])
    				flg=0;
    		if(flg){
    			printf("%d\n",n);
    			continue;
    		}
    		ll ans=1ll*n*n,sav=0,lastcnt=0;
    		for(int t=L;t;--t){
    			if(s[t]=='D') ++sav,lastcnt=0;
    			if(s[t]=='R') ans-=sav,++lastcnt;
    		}
    		if(s[1]=='R') ans-=(n-1-sav)*lastcnt;
    		sav=0;
    		for(int t=L;t;--t){
    			if(s[t]=='R') ++sav,lastcnt=0;
    			if(s[t]=='D') ans-=sav,++lastcnt;
    		}
    		if(s[1]=='D') ans-=(n-1-sav)*lastcnt;
    		printf("%lld\n",ans);
    		for(int t=1;t<=L;++t) s[t]=0;
    	}
    	return 0;
    }
    
  • 相关阅读:
    线程(中)
    线程
    生产者消费者模型
    进程的常用方法
    HTML中head与body标签
    HTTP协议
    mysql:视图,触发器,事务,存储过程,函数。
    关于MySQL中pymysql安装的问题。
    MySQL多表查询,pymysql模块。
    MySQL之单表查询
  • 原文地址:https://www.cnblogs.com/winlere/p/15926609.html
Copyright © 2020-2023  润新知