1. 程式人生 > >【浮*光】Educational Codeforces Round 51 (Rated for Div. 2) A,B,C,D 題解

【浮*光】Educational Codeforces Round 51 (Rated for Div. 2) A,B,C,D 題解

  • 最少的操作使原串變成有數字+大小寫字母的串。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<deque>
#include<cmath>
using namespace std;
typedef unsigned long long ll;

void reads(int &x){ //讀入優化(正負整數)
	int fx=1;x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')fx=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	x*=fx; //正負號
}

char s[1000010];
    
int main(){
    int T; reads(T);
    while(T--){
        scanf("%s",s+1);
        int n=strlen(s+1);
		int cnt1=0,cnt2=0,cnt3=0;
		for(int i=1;i<=n;i++){
		    if(s[i]>='0'&&s[i]<='9') cnt1++;
		    if(s[i]>='a'&&s[i]<='z') cnt2++;
		    if(s[i]>='A'&&s[i]<='Z') cnt3++;
		} 
		if(cnt1==0){
		    if(cnt2>1){
		        for(int i=1;i<=n;i++) 
		            if(s[i]>='a'&&s[i]<='z'){s[i]='1'; break;}
		        cnt2--;
		    } else if(cnt3>1){
		        for(int i=1;i<=n;i++) 
		            if(s[i]>='A'&&s[i]<='Z'){s[i]='1'; break;}
		        cnt3--;
		    }
		}
		if(cnt2==0){
		    if(cnt1>1){
		        for(int i=1;i<=n;i++) 
		            if(s[i]>='1'&&s[i]<='9'){s[i]='a'; break;}
		        cnt1--;
		    } else if(cnt3 > 1){
		        for(int i=1; i<=n; i++) 
		            if(s[i]>='A' && s[i]<='Z'){s[i]='a'; break;}
		        cnt3--;
		    }
		}
		if(cnt3==0){
		    if(cnt1>1){
		        for(int i=1; i<=n; i++) 
		            if(s[i]>='1'&&s[i]<='9'){s[i]='A'; break;}
		        cnt1--;
		    } else if(cnt2>1){
		        for(int i=1;i<=n;i++) 
		            if(s[i]>='a'&&s[i]<='z'){s[i]='A'; break;}
		        cnt2--;
		    }
		}
		printf("%s\n",s+1);
	}
    return 0;
}
  • 給出一組從l到r的所有整數,(r-l)總是奇數。
  • 將這些數字精確地分成(r-l+1)/2對,使得對於每對i、j的最大公約數等於1。
  • 列印生成的對。如果有多個解決方案,請列印其中任何一個。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<deque>
#include<cmath>
using namespace std;
typedef unsigned long long ll;

//相鄰兩數gcd為1

void reads(int &x){ //讀入優化(正負整數)
	int fx=1;x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')fx=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	x*=fx; //正負號
}
    
int main(){
    ll l,r; reads(l),reads(r); //注意要用ll
    if(l==r){ puts("NO"); return 0; }
    puts("YES");
    for(ll i=l;i<=r-1;i+=2)
    	cout<<i<<" "<<i+1<<endl;
    return 0;
}
  • 由n個整陣列成的多重集。如果數字x只出現在多重集中一次,
  • 就說它很好。希望將多重集s分成兩個多位元組a和b(其中一個可能是空的),
  • 使得兩集合中好數的數量相同。 輸出分組方案(組別 ‘A’ or ’B‘)。
  • 一個網格2行n列,此網格的每個單元格應為黑色或白色。
  • 如果兩個單元具有共同的邊界並且共享相同的顏色,則它們被認為是鄰居。
  • 如果存在屬於與B相同的元件的鄰居A,則兩個小區A和B屬於一個聯通。
  • 如果它具有正好的k個連通,那麼我們稱之為一個雙色塊。
  • 計算構成k個雙色塊的方案數。答案模998244353。

【分析】f[i][j][type] 表示 第i列,已經有j個連通塊,狀態為上下行間差異。

狀態 type: BW,BB,WW,WB( 第i列的 上行~下行 )

狀態轉移方程:

  • f[i][j][0]=f[i-1][j][0]+f[i-1][j-1][1]+f[i-1][j-1][2]+f[i-1][j-2][3];
  • f[i][j][1]=f[i-1][j][0]+f[i-1][j][1]+f[i-1][j-1][2]+f[i-1][j][3];
  • f[i][j][2]=f[i-1][j][0]+f[i-1][j-1][1]+f[i-1][j][2]+f[i-1][j][3];
  • f[i][j][3]=f[i-1][j-2][0]+f[i-1][j-1][1]+f[i-1][j-1][2]+f[i-1][j][3];
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<deque>
#include<cmath>
#include<map>
using namespace std;
typedef unsigned long long ll;

/*【D】
一個網格2行和n列,此網格的每個單元格應為黑色或白色。
如果兩個單元具有共同的邊界並且共享相同的顏色,則它們被認為是鄰居。 
如果存在屬於與B相同的元件的鄰居A,則兩個小區A和B屬於一個聯通。
如果它具有正好的k個連通,那麼我們稱之為一個雙色塊。
計算構成k個雙色塊的方案數。答案模998244353。 */

//f[i][j][type] 第i列,已經有j個連通塊,狀態為上下行間差異
//type: BW,BB,WW,WB( 第i列的 上行~下行 )
//方程:f[i][j][0]=f[i-1][j][0]+f[i-1][j-1][1]+f[i-1][j-1][2]+f[i-1][j-2][3];
//f[i][j][1]=f[i-1][j][0]+f[i-1][j][1]+f[i-1][j-1][2]+f[i-1][j][3];
//f[i][j][2]=f[i-1][j][0]+f[i-1][j-1][1]+f[i-1][j][2]+f[i-1][j][3];
//f[i][j][3]=f[i-1][j-2][0]+f[i-1][j-1][1]+f[i-1][j-1][2]+f[i-1][j][3];

void reads(int &x){ //讀入優化(正負整數)
  int fx=1;x=0;char s=getchar();
  while(s<'0'||s>'9'){if(s=='-')fx=-1;s=getchar();}
  while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
  x*=fx; //正負號
}

const int mod=998244353;
ll f[2001][2001][4];

int main(){
  int n,k; reads(n); reads(k);
  f[1][2][0]=1; f[1][1][1]=1; 
  f[1][1][2]=1; f[1][2][3]=1;
  for(int i=2;i<=n;i++) //注意:初始化第一列,從第二列開始迴圈
    for(int j=0;j<=k;j++){
      f[i][j][0]=(f[i-1][j][0]%mod+f[i-1][j-1][1]%mod+f[i-1][j-1][2]%mod+f[i-1][j-2][3]%mod)%mod;
      f[i][j][1]=(f[i-1][j][0]%mod+f[i-1][j][1]%mod+f[i-1][j-1][2]%mod+f[i-1][j][3]%mod)%mod;
      f[i][j][2]=(f[i-1][j][0]%mod+f[i-1][j-1][1]%mod+f[i-1][j][2]%mod+f[i-1][j][3]%mod)%mod;
      f[i][j][3]=(f[i-1][j-2][0]%mod+f[i-1][j-1][1]%mod+f[i-1][j-1][2]%mod+f[i-1][j][3]%mod)%mod;
    } 
  ll ans=(f[n][k][0]%mod+f[n][k][1]%mod+f[n][k][2]%mod+f[n][k][3]%mod)%mod;
  cout<<ans<<endl; return 0;
}

                                      ——時間劃過風的軌跡,那個少年,還在等你。