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;
}

  

posted @ 2019-02-17 19:27  zzd233  阅读(390)  评论(0编辑  收藏  举报