标签:
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; }
标签:
原文地址:http://www.cnblogs.com/diang/p/5723729.html