codeforce1360F. Spy-string

今世界も悪くなった

找出一个string,要和给出的n个string只有一位不同;不存在输出-1


当我看到题解的时候,是久违的我是傻逼的感觉
羊毛出自羊身上,答案出自输入里;而且数据量很小,就算把每一位所有的可能替换字母都试一遍也才260
所以。。。暴力就行

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

template<class T> void _deb(const char *name,T val){
    cout<<name<<val<<endl;
}

const int maxn=16;

string store[maxn];
bool difNum(string ans,int pos2,int len,int lim);
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int T;
    cin>>T;

    while(T--){
        int n,m;
        cin>>n>>m;
        rep(i,0,n){
            cin>>store[i];
        }

        bool flag=false;
        string ans=store[0];
//        cout<<&ans<<endl;
//        cout<<&store[0]<<endl;
        rep(reCol,0,m){
            for(char reC='a';reC<='z';reC++){
                ans[reCol]=reC;
                bool success=true;
                rep(i,1,n)
                    if(!difNum(ans,i,m,2)){
                        success=false;
                        break;
                    }
                if(success){
                    flag=true;
                    break;
                }
            }
            if(flag)
                break;
            else
                ans[reCol]=store[0][reCol];
        }

        if(flag)
            cout<<ans<<endl;
        else
            cout<<"-1"<<endl;
    }

    re 0;
}
bool difNum(string ans,int pos2,int len,int lim){
    int num=0;
    rep(i,0,len){
        if(ans[i]!=store[pos2][i])
            num++;
    }
    re num<lim;
}

但是这个题也必然可以没有这么简单,数据量这么小显然是可以用状压的!
当我们确定一个位置上要填的字母时,那么也确定了哪几个string会有不同,且每个string最多能有1个不同的地方,所以我们就可以用一个二进制序列来表示填上该字母产生的影响。通过状态转移最后得出是否可行,至于输出string,记一个前驱

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

template<class T> void _deb(const char *name,T val){
    cout<<name<<val<<endl;
}

const int maxn=16;

char ans[maxn];
string store[maxn];
int val[maxn][26];
char pre[maxn][2050];
bool dp[maxn][2050];
bool difNum(string ans,int pos2,int len,int lim);
void outInBin(int n);
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int T;
    cin>>T;

    while(T--){
        int n,m;
        cin>>n>>m;
        rep(i,0,n){
            cin>>store[i];
        }

        rep(col,0,m){
            for(char c='a';c<='z';c++){
                val[col][c-'a']=0;
                int tmp=0;
                rep(row,0,n)
                    if(c!=store[row][col])
                        tmp = tmp | (1<<row) ;
//                cout<<"col:"<<col<<" "<<"c:"<<c<<endl;
//                outInBin(tmp);
                val[col][c-'a']=tmp;
            }
        }

        mem(dp,false);
        rep(i,0,26){
            int &status=val[0][i];
//            _deb("status:",status);
            dp[0][status]=true;
            pre[0][status]='a'+i;
        }
        rep(i,1,m){
            rep(s,0,2048){
                if(!dp[i-1][s])
                    continue;
                for(char c='a';c<='z';c++){
                    int &tmp=val[i][c-'a'];

                    if( (s&tmp) ==0){
//                        _deb("col:",i),cout<<"c:"<<c<<endl;
//                        outInBin(s),outInBin(tmp);
//                        cout<<"and:"<<(s&tmp)<<endl;
//                        _deb("or:",(s|tmp));
                        dp[i][s|tmp]=true;
                        pre[i][s|tmp]=c;
                    }
                }
            }
        }

        bool isFind=false;
        int pos=0;
        rep(i,0,2048)
            if(dp[m-1][i]){
                isFind=true;
                pos=i;
                break;
            }
        if(isFind){
            drep(i,m-1,0){
//                _deb("col:",i);
//                outInBin(pos);
                char bc=pre[i][pos];
                ans[i]=bc;
                int &tmp=val[i][bc-'a'];
                pos=pos-tmp;
            }
            ans[m]=0;
            cout<<ans<<endl;
        }else
            cout<<"-1"<<endl;
    }

    re 0;
}
bool difNum(string ans,int pos2,int len,int lim){
    int num=0;
    rep(i,0,len){
        if(ans[i]!=store[pos2][i])
            num++;
    }
    re num<lim;
}
void outInBin(int n){
    cout<<"n="<<n<<endl;
    while(n){
        cout<< n%2 ;
        n=n/2;
    }
    cout<<endl;
}

猜你喜欢

转载自blog.csdn.net/white_156/article/details/106960462