Isabella Message
题意:求用密钥矩阵从从四个方向开始旋转,得到的四个对应字符串中,满足要求的最小字典序答案。详见题面。
题解:模拟,求最小字典序的时候可以把所有单词拼起来,也可以加到一个vector里直接排序。
#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> Pair;
const int maxn = 100 + 10;
const double eps = 1e-6;
int T, n, m;
string a[maxn], b[maxn], t[maxn];
vector<string> sum;
set<string> S;
struct Node {
vector<string> A;
int vis;
}ANS[5];
int flag[maxn];
bool check(int id) {
if (ANS[id].A.size() == 0) return false;
for (auto x : ANS[id].A) {
if (!S.count(x)) return false;
}
return true;
}
bool cmp(const Node &a, const Node &b) {
if (a.vis != b.vis) return a.vis > b.vis;
return a.A < b.A;
}
int main() {
//fopi;
ios::sync_with_stdio(false);
cin >> T;
for (int ca = 1; ca <= T; ca++) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
S.clear();
sum.clear();
cin >> m;
string x;
for (int i = 1; i <= m; i++) {
cin >> x;
S.insert(x);
}
for (int th = 1; th <= 4; th++) {
string s = "";
for (int i = 1; i <= n; i++)
for (int j = 0; j < n; j++)
if (b[i][j] == '*') {
if (a[i][j] == '.') s += " ";
else s += a[i][j];
}
sum.push_back(s);
for (int j = 0; j < n; j++) {
t[j+1] = "";
for (int i = n; i >= 1; i--) {
t[j+1] += b[i][j];
}
}
for (int i = 1; i <= n; i++) b[i] = t[i];
}
for (int i = 0; i < 4; i++) {
ANS[i].A.clear();
ANS[i].vis = 0;
}
for (int i = 0; i < 4; i++) {
string ans = "";
for (int j = 0; j < 4; j++) {
int t = (i+j) % 4;
ans += sum[t];
}
stringstream ss(ans);
string s;
while(ss >> s) ANS[i].A.push_back(s);
if (check(i)) ANS[i].vis = 1;
}
cout << "Case #" << ca <<": ";
int f = 0;
for (int i = 0; i < 4; i++) {
if (ANS[i].vis) f++;
}
if (!f) {
cout << "FAIL TO DECRYPT" << endl;
continue;
}
sort(ANS, ANS+4, cmp);
for (int i = 0; i < ANS[0].A.size(); i++) {
if (i) cout << " ";
cout << ANS[0].A[i];
}
cout << endl;
}
}