题目大意:给一个n*n的矩阵,n为偶数,矩阵由小写字母和'.'组成,'.'表示空格,再给一个n*n矩阵,由'.'和'*'组成,'*'表示洞,'.'表示障碍。现在将2张卡片重合,将能看到的字符从上往下从左往右依次取出组成一个新单词。卡片可以顺时针旋转90度,再取出能看到的单词,一共有4个单词,4个单词再依次组成一个句子,因为卡片是连续转动的,所以4个单词首尾相连,任取一个做句子头,所以句子一共也是4个。再给m个单词,求出字典序最小的句子并要求句子中每个单词都在给定的m个单词中。
题目分析:简单模拟题。比赛的时候都看错了题目。。。最后还兴致勃勃的敲起了字典树。。。没看到空格。。。如果算空格的话就比较简单了。将组成的句子中单词一一挑出来,在给定的m个单词中找就ok了。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<string> #include<map> #include<vector> #include<algorithm> using namespace std; const int N = 55; map<string,int>lcm; char s[N][N]; int num; struct msk { int x,y; }mask[1000]; int n,m; int cmp(struct msk a,struct msk b) { if(a.x != b.x) return a.x < b.x; else return a.y < b.y; } int cmp1(string a,string b) { int i,j; i = j = 0; while(a[i] == '.') i ++; while(b[j] == '.') j ++; while(i < a.length() && j < b.length()) { if(a[i] == b[j]) i ++,j ++; else return a[i] < b[j]; } } void Rotate() { for(int i = 1;i < num;i ++) { int t= mask[i].x; mask[i].x = mask[i].y; mask[i].y = n - t - 1; } sort(mask + 1,mask + num,cmp); } int main() { int t,cas; int i,j; cas = 0; scanf("%d",&t); while(t --) { scanf("%d",&n); gets(s[0]); for(i = 0;i < n;i ++) gets(s[i]); num = 1; for(i = 0;i < n;i ++) { for(j = 0;j < n;j ++) { if(getchar() == '*') { mask[num].x = i; mask[num ++].y = j; } } getchar(); } scanf("%d",&m); lcm.clear(); string word; for(i = 0;i < m;i ++) { cin>>word; lcm[word] = 1; } string str[4]; for(i = 0;i < 4;i ++) str[i] = ""; for(i = 0;i < 4;i ++) { for(j = 1;j < num;j ++) str[i] += s[mask[j].x][mask[j].y]; Rotate(); } string ans[4]; for(i = 0;i < 4;i ++) { for(j = 0;j < 4;j ++) ans[i] += str[(i + j)%4]; } // for(i = 0;i < 4;i ++) // cout<<ans[i]<<endl; // cout<<endl; sort(ans,ans + 4,cmp1); // for(i = 0;i < 4;i ++) // cout<<ans[i]<<endl; string tmp; bool flag; vector<string> out; for(i = 0;i < 4;i ++) { flag = true; out.clear(); j = 0; while(j < ans[i].length()) { while(j < ans[i].length() && ans[i][j] == '.') j ++; if(j >= ans[i].length()) break; tmp = ""; while(j < ans[i].length() && ans[i][j] != '.') tmp += ans[i][j],j ++; if(lcm[tmp] == 0) { flag = false; break; } else { out.push_back(tmp); //j ++; } } if(flag) break; } printf("Case #%d:",++cas); if(i < 4) { for(j = 0;j < out.size();j ++) cout<<" "<<out[j]; cout<<endl; } else puts(" FAIL TO DECRYPT"); } return 0; } //31MS 324K