链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3703
题意:
给两个6行5列的字母矩阵,找出满足如下条件的“密码”:密码中的每个字母在两个矩阵的对应列中均出现。
例如,左数第2个字母必须在两个矩阵中的左数第2列中均出现。
给定k(1≤k≤7777),你的任务是找出字典序第k小的密码。如果不存在,输出NO。
分析:
经典的解码问题。首先求出答案每一列的所有可能字母,然后逐位解码即可。
具体实现见代码。
代码:
1 import java.io.*; 2 import java.util.*; 3 4 public class Main { 5 static char G[][][] = new char[2][6][9]; 6 7 public static void main(String args[]) { 8 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 9 10 int T = cin.nextInt(); 11 while(T --> 0) { 12 int k = cin.nextInt(); 13 cin.nextLine(); // 清空缓存区 14 for(int t = 0; t < 2; t++) { 15 for(int r = 0; r < 6; r++) { 16 G[t][r] = cin.nextLine().toCharArray(); 17 } 18 } 19 20 @SuppressWarnings("unchecked") 21 ArrayList<Character> a[] = new ArrayList[5]; // a[c]: 答案第c列的所有可能字母 22 for(int i = 0; i < 5; i++) a[i] = new ArrayList<Character>(); 23 24 boolean has[][][] = new boolean[2][5][26]; // 第t个矩阵的第c列是否有字母ch 25 for(int c = 0; c < 5; c++) { 26 for(int t = 0; t < 2; t++) { 27 for(int r = 0; r < 6; r++) { 28 int ch = G[t][r][c] - 'A'; 29 has[t][c][ch] = true; 30 } 31 } 32 for(int i = 0; i < 26; i++) 33 if(has[0][c][i] && has[1][c][i]) a[c].add((char)(i+'A')); 34 } 35 36 int up = 1; 37 for(int i = 0; i < 5; i++) up *= a[i].size(); 38 if(k > up) { 39 System.out.println("NO"); 40 continue; 41 } 42 43 k--; // 解码 44 for(int i = 0; i < 5; i++) { 45 up /= a[i].size(); 46 System.out.print(a[i].get(k/up)); 47 k %= up; 48 } 49 System.out.println(); 50 } 51 cin.close(); 52 } 53 }