Codeforces 1099E - Nice table - [好題]

題目連接:https://codeforces.com/problemset/problem/1099/Ec++

You are given an $n×m$ table, consisting of characters «A», «G», «C», «T». Let's call a table nice, if every $2×2$ square contains all four distinct characters. Your task is to find a nice table (also consisting of «A», «G», «C», «T»), that differs from the given table in the minimum number of characters.spa

Input
First line contains two positive integers $n$ and $m$ — number of rows and columns in the table you are given $(2≤n,m,n×m≤300000)$. Then, $n$ lines describing the table follow. Each line contains exactly $m$ characters «A», «G», «C», «T».code

Output
Output $n$ lines, $m$ characters each. This table must be nice and differ from the input table in the minimum number of characters.blog

Examples
Input
2 2
AG
CT
Output
AG
CT
Input
3 5
AGCAG
AGCAG
AGCAG
Output
TGCAT
CATGC
TGCAT
Note
In the first sample, the table is already nice. In the second sample, you can change $9$ elements to make the table nice.ci

 

題解:element

一個 nice table 必然屬於如下兩種狀況:get

  一、每行都由兩個字符交替組成,相鄰兩行的字符集合交集爲空;input

  二、每列都由兩個字符交替組成,相鄰兩列的字符集合交集爲空。string

對於上述兩種狀況中的一種,不妨先對於每行,枚舉其可能的字符集,而對於一個字符集,又有正序和逆序兩種狀況。it

 

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
const char choice[6][2]={{'A','C'},{'A','G'},{'A','T'},{'C','G'},{'C','T'},{'G','T'}};

int n,m;
string str[maxn];

int ord[2][maxn][6],cnt[2][maxn];

string out[maxn];
void print(int rc,int k)
{
    for(int i=0;i<n;i++) out[i]="";
    if(rc==0) //R
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                out[i]+=choice[(i&1)?5-k:k][(j&1)^ord[0][i][k]];
    }
    else //C
    {
        for(int j=0;j<m;j++)
            for(int i=0;i<n;i++)
                out[i]+=choice[(j&1)?5-k:k][(i&1)^ord[1][j][k]];
    }
    for(int i=0;i<n;i++) cout<<out[i]<<endl;
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>str[i];

    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<n;i++)
    {
        for(int k=0;k<6;k++)
        {
            int now1=0, now2=0;
            for(int j=0;j<m;j++)
            {
                now1+=(str[i][j]!=choice[(i&1)?5-k:k][j&1]);
                now2+=(str[i][j]!=choice[(i&1)?5-k:k][(j&1)^1]);
            }
            ord[0][i][k]=now1<now2?0:1; //0正序,1逆序
            cnt[0][k]+=min(now1,now2);
        }
    }
    for(int j=0;j<m;j++)
    {
        for(int k=0;k<6;k++)
        {
            int now1=0, now2=0;
            for(int i=0;i<n;i++)
            {
                now1+=(str[i][j]!=choice[(j&1)?5-k:k][i&1]);
                now2+=(str[i][j]!=choice[(j&1)?5-k:k][(i&1)^1]);
            }
            ord[1][j][k]=now1<now2?0:1; //0正序,1逆序
            cnt[1][k]+=min(now1,now2);
        }
    }

    int ans=0x3f3f3f3f,RC,K;
    for(int rc=0;rc<=1;rc++)
    {
        for(int k=0;k<6;k++)
        {
            if(cnt[rc][k]<ans) ans=cnt[rc][k], RC=rc, K=k;
        }
    }
    //cout<<ans<<endl;
    print(RC,K);
}

(注:借鑑了https://www.luogu.org/blog/xht37/cf1098bcf1099e-nice-table的代碼,到了這個點心態真的要放平……心態不穩代碼基本不可能AC……)

相關文章
相關標籤/搜索