• Codeforces 1098B. Nice table 构造


    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1098B.html

    题解

      首先,我们来证明一个结论:

      合法的矩阵要么满足每列只有两种字符,要么满足每行只有两种字符。

      然后直接枚举就好了。

      代码并不是那么好写。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL read(){
    	LL x=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return x;
    }
    const int N=300005;
    const LL INF=1LL<<60;
    int n,m;
    char ch[4]={'A','C','G','T'};
    int v[300],a[N],b[N],t[N],ans;
    char s[N];
    int &A(int i,int j){
    	return a[(i-1)*m+j];
    }
    int &B(int i,int j){
    	return b[(i-1)*m+j];
    }
    int &T(int i,int j){	
    	return t[(i-1)*m+j];
    }
    int get(int c,int v1,int v2){
    	int c1=0,c2=0;
    	for (int i=1;i<=n;i++){
    		if (i&1){
    			c1+=A(i,c)!=v1;
    			c2+=A(i,c)!=v2;
    		}
    		else {
    			c1+=A(i,c)!=v2;
    			c2+=A(i,c)!=v1;
    		}
    	}
    	if (c1<=c2){
    		for (int i=1;i<=n;i++)
    			if (i&1)
    				T(i,c)=v1;
    			else
    				T(i,c)=v2;
    		return c1;
    	}
    	else {
    		for (int i=1;i<=n;i++)
    			if (i&1)
    				T(i,c)=v2;
    			else
    				T(i,c)=v1;
    		return c2;
    	}
    }
    int get2(int c,int v1,int v2){
    	int c1=0,c2=0;
    	for (int i=1;i<=m;i++){
    		if (i&1){
    			c1+=A(c,i)!=v1;
    			c2+=A(c,i)!=v2;
    		}
    		else {
    			c1+=A(c,i)!=v2;
    			c2+=A(c,i)!=v1;
    		}
    	}
    	if (c1<=c2){
    		for (int i=1;i<=m;i++)
    			if (i&1)
    				T(c,i)=v1;
    			else
    				T(c,i)=v2;
    		return c1;
    	}
    	else {
    		for (int i=1;i<=m;i++)
    			if (i&1)
    				T(c,i)=v2;
    			else
    				T(c,i)=v1;
    		return c2;
    	}
    }
    int main(){
    	v['A']=0,v['C']=1,v['G']=2,v['T']=3;
    	n=read(),m=read();
    	for (int i=1;i<=n;i++){
    		scanf("%s",s+1);
    		for (int j=1;j<=m;j++)
    			A(i,j)=v[s[j]];
    	}
    	ans=n*m;
    	for (int i=0;i<4;i++)
    		for (int j=i+1;j<4;j++){
    			int now=0;
    			int ii=-1,jj;
    			for (int k=0;k<4;k++)
    				if (k!=i&&k!=j)
    					if (!~ii)
    						ii=k;
    					else
    						jj=k;
    			for (int k=1;k<=m;k++)
    				if (k&1)
    					now+=get(k,i,j);
    				else
    					now+=get(k,ii,jj);
    			if (now<ans){
    				ans=now;
    				for (int i=1;i<=n*m;i++)
    					b[i]=t[i];
    			}
    		}
    	for (int i=0;i<4;i++)
    		for (int j=i+1;j<4;j++){
    			int now=0;
    			int ii=-1,jj;
    			for (int k=0;k<4;k++)
    				if (k!=i&&k!=j)
    					if (!~ii)
    						ii=k;
    					else
    						jj=k;
    			for (int k=1;k<=n;k++)
    				if (k&1)
    					now+=get2(k,i,j);
    				else
    					now+=get2(k,ii,jj);
    			if (now<ans){
    				ans=now;
    				for (int i=1;i<=n*m;i++)
    					b[i]=t[i];
    			}
    		}
    	for (int i=1;i<=n;i++,puts(""))
    		for (int j=1;j<=m;j++)
    			putchar(ch[B(i,j)]);
    	return 0;
    }
    

      

  • 相关阅读:
    《秋日》 -- 程颢
    《安乐吟》 -- 邵雍
    《大学》笔记
    《跨越鸿沟》笔记
    庄子《齐物论》—— 方生方死、因是因非是对立统一规律的起源
    《饮酒(其五)》陶渊明
    《亲密关系》笔记
    《人生的智慧》笔记
    《历史的教训》笔记
    《格鲁夫给经理人的第一课》笔记
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/CF1098B.html
Copyright © 2020-2023  润新知