您的位置:首页 > 其它

hdu4119 模拟旋转矩阵mask解密

2016-07-31 19:37 501 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: