1 条题解
-
0
#include <bits/stdc++.h> using namespace std; char s[51100][110];//s[1]-s[n]为小红修改后的单词 ,s[0]为需要小红给出的密语 int Map[150][150], rd[150], ys[150];bool v[150]; //Map[c1][c2]表示原字典序中错误字母c1在错误字母c2前。 //rd[c]表示错误字母c有多少入度(多少个错误字母在c前) //ys[c]表示错误字母c对应的原字母 //v[c]表示错误字母c有出现过 int main() { int n, m;scanf("%d%d", &n, &m);if(m <= 1){printf("0\n");return 0;}//如果单词只有1个,那无法破解 memset(v, 0, sizeof(v)); for(int i=1; i<=m; i++)//输入m个小红修改过的单词 { scanf("%s", s[i]);for(int j=0; j<strlen(s[i]); j++)v[s[i][j]]=1;//标记这些错误单词的每个字母出现过 } scanf("%s", s[0]);//输入小红给出的密语 for(int i=0; i<strlen(s[0]); i++)if(!v[s[0][i]]){printf("0\n");return 0;}//如果密语的字母没有出现过也没法破解 //下来建立拓扑关系 memset(rd, 0, sizeof(rd)); memset(Map, 0, sizeof(Map)); for(int i=2; i<=m; i++)//每个错误单词都和前一个单词进行对照,看看是那个字母影响了它们原来的字典序,从而判断这两个错误字母原来的前后顺序 { int l1 = strlen(s[i-1]), l2 = strlen(s[i]); for(int j=0; j<min(l1, l2); j++) { if(s[i-1][j] != s[i][j]){Map[s[i-1][j]][s[i][j]] = 1;rd[s[i][j]]++;break;} } } for(int i=1; i<=n; i++)//每次找出一个(而且只能刚好一个)入度为0的字母,它就是原来的第i个字母 { int t = 0;//当前这一次只能找到一个入度为0的字母,如果找到多于1个,则无法破解 char c1; for(char c='a'; c < 'a' + n; c++) { if(rd[c] == 0) { t++;if(t > 1){printf("0\n");return 0;} rd[c] = -1; ys[c] = 'a' + i - 1; c1 = c; } } if(t == 0){printf("0\n");return 0;}//找不到入度为0的字母,也无法破解 for(char c2='a'; c2 < 'a' + n; c2++)if(Map[c1][c2] == 1)rd[c2]--; } for(int i=0; i<strlen(s[0]); i++)printf("%c", ys[s[0][i]]); printf("\n"); return 0; }
- 1
信息
- ID
- 770
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- 递交数
- 34
- 已通过
- 20
- 上传者