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

时间: 2024-11-05 15:54:12

Codeforces 1098B. Nice table 构造的相关文章

Codeforces 338D GCD Table 中国剩余定理

题目链接:点击打开链接 给定n*m的矩阵,[i,j]的点值为gcd(i,j) 给定一个k长的序列,问是否能匹配上 矩阵的某一行的连续k个元素 思路: 我们要求出一个解(i,j) 使得 i<=n && j<=m 此时输出 YES 对于j j % b[0] = 0 j+1 % b[1] = 0 ··· j+l % b[l] = 0 根据定理:若 a == b (mod n) => (a+c) == b+c (mod n) 所以将上式变换为 j % b[0] = 0 j % b

Codeforces 534C Polycarpus&#39; Dice 构造

题意:给你n个筛子,第 i 个筛子有 可以表示范围 1-a[i]的数,给你最后筛子和,问你每个筛子不可能的值有多少个. 解题思路:得到每个筛子的取值范围. 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月13日 星期一 00时38分58秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #includ

Codeforces 432E Square Tiling(构造+贪心)

我们通常这么写 using (SqlDataReader drm = sqlComm.ExecuteReader()) { drm.Read();//以下把数据库中读出的Image流在图片框中显示出来. MemoryStream ms = new MemoryStream((byte[])drm["Logo"]); Image img = Image.FromStream(ms); this.pictureBox1.Image = img; } 我的写数据 private void b

【打CF,学算法——二星级】CodeForces 237B Young Table (构造)

[CF简介] 提交链接:CF 237B 题面: B. Young Table time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You've got table a, consisting of n rows, numbered from 1 to n. The i-th line of table a contains ci

Codeforces 482A Diverse Permutation(构造)

题目链接:Codeforces 482A Diverse Permutation 题目大意:给定N和K,即有一个1~N的序列,现在要求找到一个排序,使得说所有的|pi?pi+1|的值有确定K种不同. 解题思路:构造,1,K+1,2,K,3,K-1,... K+2,K+3 ... N. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn

CodeForces 404C Restore Graph (构造)

题意:让人构造一个图,满足每个结点边的数目不超过 k,然后给出每个结点到某个结点的最短距离. 析:很容易看出来如果可能的话,树是一定满足条件的,只要从头开始构造这棵树就好,中途超了int...找了好久. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include

codeforces #550D Regular Bridge 构造

题目大意:给定k(1≤k≤100),要求构造一张简单无向连通图,使得存在一个桥,且每一个点的度数都为k k为偶数时无解 证明: 将这个图缩边双,能够得到一棵树 那么一定存在一个叶节点,仅仅连接一条桥边 那么这个边双内部全部点度数之和为偶数 除掉连出去的桥边外度数之和为奇数 故不合法 然后k为奇数的时候我们仅仅须要构造两个对称的边双被一条桥边连接的图即可了 因为每一个点度数为k.因此每一边至少须要k+1个点 可是k+1个点奇偶性不合法.因此每一边至少须要k+2个点 如今问题转化成了给定一个度数数组

Codeforces 482B Interesting Array 构造+线段树判可行

题目链接:点击打开链接 题意: 构造一个n长的序列,m个限制: 每个限制[l, r] q 序列要满足 区间[l,r]的所有数 & 起来结果是q 思路: 直接构造,然后判可行就好了.. #include <stdio.h> #include <cstring> #include <iostream> #include <map> template <class T> inline bool rd(T &ret) { char c;

Codeforces 468A 24 Game(构造)

题目链接:Codeforces 468A 24 Game 题目大意:给出n,表示有1~n这n个数,判断能否进n-1次操作获得24. 解题思路:4,5的情况可以手动处理出来,然后对于大于4,5的情况可以通过两两相减,形成若干个1. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main () { int n; scanf("%d",