hdu4119 模拟旋转矩阵mask解密

http://acm.hdu.edu.cn/showproblem.php?pid=4119

解密文,解密的方式是有一个字符矩阵,一个mask矩阵,如果一个mask矩阵,mask矩阵盖在字符举证上,从上到下,从左到右露出来的是密文的一部分,然后把mask矩阵旋转一周,四个90度下的密文一部分加在一起就是密文的内容,但是因为初识的mask角度未知,所以密文不止一种。给出一个认识的字符串的集合,答案是是由集合内组成的前提下字典序最小的密文。

 

我的原来的代码改不过来了,照着别人ac的代码模仿了一份,发现错误:

1.出现在我以为可能的密文就是4个90度下的字符串数组的排列组合的连接,实际上4个90度是有先后关系的,密文只有4种。

2.我没有合并中间连续的多个空格.解决这个的方式其实是优点类似于自动机的。不问由来,只问状态

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<cctype>
#include<stack>
#include<queue>
#include<set>
#include<sstream>
#include<map>
#include<ctime>
using namespace std;
#define For(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,k,n) for(int i=n;i>=k;i--)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define NEG(a) memset(a,-1,sizeof(a));
#define FILL(a) memset(a,0x3f,sizeof(a));
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define print(b,a) cout<<b<<"="<<a<<endl;
#define printbin(b,a){int tmp=a;string s;do{s+=tmp%2+'0';tmp/=2;}while(tmp);reverse(s.begin(),s.end());cout<<"bin "<<b<<"="<<s<<endl;}
#define printarr(i,a,f,b) {For(i,f,b) printf("%d ",a[i]); printf("\n");}


struct node
{
    int x,y;
    bool operator <(const node& rhs) const
    {
        if(x!=rhs.x) return x<rhs.x;
        else return y<rhs.y;
    }
    bool operator ==(const node& rhs) const
    {
        return x==rhs.x&&y==rhs.y;
    }
};
int n,sz;
char mat1[60][60],mat2[60][60],buf[2000];
string s[4];
map<string,int>dic;
map<node,int>isb;
vector<node>b,btmp;
set<string>ans;
node rot(node tmp,int idx){
    int x=tmp.x,y=tmp.y;
    if(idx==0)
        return tmp;
    else if(idx==1) 
    {
        return node{y,n+1-x};
    }
    else if(idx==2)
    {
        return node{n+1-x,n+1-y};
    }
    else 
    {
        return node{n+1-y,x};
    }
}
string getstr(int idx)
{
    isb.clear();
    btmp.clear();
    btmp=b;
    For(i,0,sz-1)
    {
        btmp[i]=rot(btmp[i],idx);
        //printf("%d %d\n",btmp[i].x,btmp[i].y);
        isb[btmp[i]]=1;
    }
    string ret;
    For(i,1,n)
    {
        For(j,1,n)
        {
            if(isb[node{i,j}]==1)
            {
                //printf("i=%d j=%d\n",i,j);
                ret+=mat1[i][j];
            }
        }
    }
    return ret;

}
string preprocess(string s)///deal with blanks  
{  
    string ret("");  
    int len = s.length();  
    bool flag = true;///ignore blank  
    int i = 0;  
    while(s[i] == '.')i++;  
    for(; i < len; ++i)  
    {  
        if(s[i] == '.')  
        {  
            flag = false;///blank delay!!! only mark it when encounter blank, because you may encounter blanks!!!  
        }//the blank after the first word activated the flag   
        else//while the second word set the first blank and at the same time eliminated the flag  
        {  
            if(!flag)  
            {  
                ret += ' ';  
                flag = true;  
            }  
            ret += s[i];  
        }  
    }  
    return ret;  
}  
bool check(string s)  
{  
    int len = s.length();  
    string key;  
    for(int i = 0; i < len; ++i)  
    {  
        if(s[i] == ' ')  
        {  
            if(dic.find(key) == dic.end()) return false;  
            key.clear();  
        }  
        else key += s[i];  
    }  
    if(dic.find(key) == dic.end()) return false;  
    return true;  
} 
int r[4][4] =  
{  
    {0,1,2,3},  
    {1,2,3,0},  
    {2,3,0,1},  
    {3,0,1,2}  
};//circle shift 
int main()
{
    freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    For(kases,1,T)
    {
        scanf("%d",&n); getchar();

        For(i,1,n) 
            gets(mat1[i]+1);
        b.clear();
        For(i,1,n) {
            gets(mat2[i]+1);
            For(j,1,n)
            {
                if(mat2[i][j]=='*')
                {
                    b.push_back(node{i,j});
                    //printf("i=%d j=%d\n",i,j);
                }
            }
        }
        sz=b.size();

        int m;
        scanf("%d",&m);
        dic.clear();
        For(i,1,m) 
        {
            string tmp;
            cin>>tmp;
            dic[tmp]=1;
        }

        For(i,0,3){
            s[i]=getstr(i);
            //cout<<"i="<<i<<" "<<s[i]<<endl;
        }
        ans.clear();
        for(int i = 0; i < 4; ++i)  
        {  
             string tocheck("");  
             for(int j = 0; j < 4; ++j) tocheck += tostring[r[i][j]];///concatenate string  
             string st = preprocess(tocheck);  
             if(check(st)) ans.insert(st);  
         }  
        if(ans.size()!=0)
            cout<<"Case #"<<kases<<": "<<*ans.begin()<<endl;
        else 
            cout<<"Case #"<<kases<<": "<<"FAIL TO DECRYPT"<<endl;
    }
    return 0;
}
View Code

 

posted @ 2016-07-31 19:37  aidgn  阅读(380)  评论(0编辑  收藏  举报