(i,j)——> (j,n-i+1) 坐标变换公式,从1,1开始。
先求出4个字符串,然后改变连接顺序,组成新的4个字符串。然后查找是否全部由单词本中的单词组成。
重写一遍就过了,真心不知道当时哪错了。
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<string>
using namespace std;
char mp[60][60];
char mp2[60][60];
int dx[3000],dy[3000];
int n,m,ans;
struct node{int x,y;}d[3000];
string word[105];
string b[5];
vector<int> way[10];
bool cmp(const node &aa,const node &bb)
{
if(aa.x==bb.x) return aa.y<bb.y;
return aa.x<bb.x;
}
bool cmp2(vector<int> a,vector<int> b)
{
for(int i=0;i<a.size();i++)
if(a[i]<b[i]) return true;
else if(a[i]>b[i]) return false;
return a.size()<b.size();
}
int search(int pos,int k)
{
for(int i=0;i<m;i++)
{
int tmp=pos,ok=1;
for(int j=0;word[i][j];j++)
{
if(b[k][tmp++]!=word[i][j]) {ok=0;break;}
}
if(ok&&(b[k][tmp]=='.'||b[k][tmp]=='\0')) {way[ans].push_back(i);return tmp-1;}
}
way[ans].clear();
return -1;
}
int main()
{
int ca;
scanf("%d",&ca);
for(int cas=1;cas<=ca;cas++)
{
for(int i=0;i<5;i++) b[i]="";
string a[5];
scanf("%d",&n);getchar();
for(int i=1;i<=n;i++)
gets(mp[i]+1);
for(int i=1;i<=n;i++)
gets(mp2[i]+1);
scanf("%d",&m);
for(int i=0;i<m;i++)
cin>>word[i];
sort(word,word+m);
int top=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(mp2[i][j]=='*') d[top].x=i,d[top++].y=j;
for(int i=0;i<4;i++)
{
for(int j=0;j<top;j++)
{
a[i]+=mp[d[j].x][d[j].y];
int t=d[j].x;
d[j].x=d[j].y;
d[j].y=n-t+1;
}
sort(d,d+top,cmp);
}
for(int i=0;i<4;i++)
{
for(int c=1,j=i;c<=4;j++,c++)
{
j%=4;
b[i]+=a[j];
}
}
ans=0;
for(int i=0;i<4;i++)
{
way[ans].clear();
int j,len=b[i].length();
for(j=0;j<len;j++)
{
if(b[i][j]=='.') continue;
int tmp=search(j,i);
if(tmp==-1) break;
else j=tmp;
}
if(j==len) ans++;
}
sort(way,way+ans,cmp2);
if(ans)
{
cout<<"Case #"<<cas<<":";
for(int i=0;i<way[0].size();i++)
cout<<' '<<word[way[0][i]];
}
else
{
cout<<"Case #"<<cas<<": FAIL TO DECRYPT";
}
cout<<endl;
}
return 0;
}