标签:
题意:
给出两个6行5列的字母矩阵,一个密码满足:密码的第i个字母在两个字母矩阵的第i列均出现。
然后找出字典序为k的密码,如果不存在输出NO
分析:
我们先统计分别在每一列均在两个矩阵出现的字母,然后从小到大排好序。
对于第一个样例来说,我们得到ACDW、BOP、GMOX、AP、GSU
则一共有4×3×4×2×3=288种密码,我们先计算这个数列的后缀积:288、72、24、6、3、1
要确定第一个字母,如果1≤k≤72,则是A;如果73≤k≤144,则是C,以此类推。
确定第二个字母是类似的,用k%72+1与24去比较。
代码实现中,字典序是从0开始的。
1 //#define DEBUG 2 #include <cstdio> 3 #include <cstring> 4 5 char G[2][6][5], ans[6], select[6][5]; 6 int vis[2][26], hehe[6], cnt[5]; 7 8 int main() 9 { 10 //freopen("in.txt", "r", stdin); 11 12 int T; 13 scanf("%d", &T); 14 hehe[5] = 1; 15 while(T--) 16 { 17 memset(cnt, 0, sizeof(cnt)); 18 int k; 19 scanf("%d", &k); 20 k--; //字典序标号从0开始 21 for(int i = 0; i < 2; ++i) 22 for(int j = 0; j < 6; ++j) 23 scanf("%s", G[i][j]); 24 25 for(int i = 0; i < 5; ++i) 26 { 27 memset(vis, 0, sizeof(vis)); 28 for(int j = 0; j < 2; ++j) 29 for(int k = 0; k < 6; ++k) 30 vis[j][G[j][k][i]-‘A‘] = 1; 31 for(int j = 0; j < 26; ++j) 32 if(vis[0][j] && vis[1][j]) 33 select[i][cnt[i]++] = ‘A‘ + j; 34 } 35 36 #ifdef DEBUG 37 for(int i = 0; i < 5; ++i) 38 { 39 for(int j = 0; j < select[i].size(); ++j) 40 printf("%c", select[i][j]); 41 puts(""); 42 } 43 #endif // DEBUG 44 45 for(int i = 4; i >= 0; --i) 46 hehe[i] = cnt[i] * hehe[i+1]; 47 if(k >= hehe[0]) 48 { 49 puts("NO"); 50 continue; 51 } 52 for(int i = 0; i < 5; ++i) 53 { 54 int m = k / hehe[i+1]; 55 ans[i] = select[i][m]; 56 k = k % hehe[i+1]; 57 } 58 ans[5] = ‘\0‘; 59 60 printf("%s\n", ans); 61 } 62 63 return 0; 64 }
解法二:
因为密码最多有65 = 7776种,所以可以按字典序从小到大枚举。
思维难度小,写起来更快更对。
1 #include <cstdio> 2 #include <cstring> 3 4 int k, cnt; 5 char G[2][6][5], ans[6]; 6 7 bool dfs(int col) 8 { 9 if(col == 5) 10 { 11 if(++cnt == k) 12 { 13 ans[col] = ‘\0‘; 14 printf("%s\n", ans); 15 return true; 16 } 17 return false; 18 } 19 20 bool vis[2][26]; 21 memset(vis, false, sizeof(vis)); 22 for(int i = 0; i < 2; ++i) 23 for(int j = 0; j < 6; ++j) 24 vis[i][G[i][j][col] - ‘A‘] = 1; 25 for(int i = 0; i < 26; ++i) 26 if(vis[0][i] && vis[1][i]) 27 { 28 ans[col] = i + ‘A‘; 29 if(dfs(col+1)) return true; 30 } 31 return false; 32 } 33 34 int main() 35 { 36 //freopen("in.txt", "r", stdin); 37 int T; 38 scanf("%d", &T); 39 while(T--) 40 { 41 scanf("%d", &k); 42 for(int i = 0; i < 2; ++i) 43 for(int j = 0; j < 6; ++j) 44 scanf("%s", G[i][j]); 45 46 cnt = 0; 47 if(!dfs(0)) puts("NO"); 48 } 49 50 return 0; 51 }
标签:
原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4175508.html