POJ 1496 Word Index
这道题应该算是一般的题,由于有多组测试数据,但是每组测试数据的情况数并不多,只到 80000 多,所以我是先初始化了一张表,然后它输入什么,我就直接在表里找就可以了。
原题地址:http://poj.org/problem?id=1496
POJ 1496 单词索引
问题描述
编码方案 (encoding scheme) 经常用于加密存储和传输时的数据。现在,我们开发了一种简单的编码方案,这种方案可以将某些特殊的长度为 5 或以下的(小写)字母编码成整数。
根据英语字母表 {a, b, c, … , z} 组成的合法单词可以严格地按照字典序排列。在这里,“合法的”单词的含义是,单词中的字母从左向右是严格递增的;就是说,对于合法的单词中的每一对字母,第二个字母总是在第一个字母的字母表 {a, b, c, … , z} 的后面。例如:
abc aep gwz
以上全都是合法的 3 字母单词,但是下面这些:
aab are cat
不是合法的。
每一个合法的单词,对应着一个整数,这个整数就是这个单词在所有合法单词中的字典序位置。就是说:
a -> 1 b -> 2 . . z -> 26 ab -> 27 ac -> 28 . . az -> 51 bc -> 52 . . vwxyz -> 83681
你的程序需要读取若干行的输入数据。输入数据中,每行只有一个单词,并且保证这个单词的长度至少是 1 至多是 5. 对于每个读入的单词,如果它是不合法的单词,请输出数字 0. 如果是一个合法的单词,请给出这个单词在合法单词表中的字典序。
输入数据
输入数据由一系列的单词组成,每个单词占一行。每个单词至少一个字母,至多 5 个字母。单词只会由小写字母 {a,b,…,z} 构成。单词的第一个字母一定会是每行的第一个字符。
输入数据将以文件结束符 (EOF) 结束。
输出数据
输出数据中,每行应该输出一个从 0 到 83681 的整数。输出的数字的最高位应该是每行的第一个字符。每行输入应该对应一行输出。
样例输入
z a cat vwxyz
样例输出
26 1 0 83681
解题思路
由于只有 83681 种合法情况,我在程序中预处理了一张表,然后每次输入只需在表里查找相应的字符串,找出对应的数字即可。如果用 C++ 的话,使用标准库里的 <map> 应该非常方便。我是用 Java 做的这题,对于 Java 库里的内建数据结构还不够了解,所以写得有点笨,或许有写得更快的方法。我在表里用了二分查找……
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | import java.util.*; public class Main { protected static byte[][] table; protected static void initialize() { table = new byte[83682][5]; int bound = 1; for (byte e = 0; e <= 26; ++e) { for (byte d = (byte)(e == 0 ? 0 : e + 1); d <= 26; ++d) { for (byte c = (byte)(d == 0 ? 0 : d + 1); c <= 26; ++c) { for (byte b = (byte)(c == 0 ? 0 : c + 1); b <= 26; ++b) { for (byte a = (byte)(b + 1); a <= 26; ++a) { table[bound][0] = e; table[bound][1] = d; table[bound][2] = c; table[bound][3] = b; table[bound][4] = a; ++bound; } } } } } } protected static int compare(byte[] a, byte[] b) { for (int i = 0; i < 5; ++i) if (a[i] != b[i]) return a[i] - b[i]; return 0; } protected static int bsearch(byte[] val, int start, int end) throws Exception { if (start == end) if (compare(val, table[start]) == 0) return start; else throw new Exception("Value not found."); if (start > end) throw new Exception("Value not found."); int middle = (start + end) / 2; int result = compare(val, table[middle]); if (result == 0) // Which means the value was found at middle. return middle; else if (result > 0) // Which means the value is large than the middle one. return bsearch(val, middle + 1, end); else return bsearch(val, start, middle - 1); } protected static int search(byte[] val) { // Check whether the value is a valid word. int i = 1; for ( ; i < 4; ++i) if (val[i] != 0) break; for ( ; i < 5; ++i) if (val[i] <= val[i - 1]) return 0; // Search the word in the table. try { return bsearch(val, 1, 83681); } catch (Exception ex) { return 0; } } protected static byte[] process(String str) { byte[] result = new byte[5]; // Assumes that the string is not empty. for (int i = 0; i < (5 - str.length()); ++i) result[i] = 0; for (int i = 5 - str.length(); i < 5; ++i) result[i] = (byte)(str.charAt(i - 5 + str.length()) - 'a' + 1); return result; } public static void main(String[] args) { initialize(); Scanner cin = new Scanner(System.in); while (cin.hasNextLine()) { String str = cin.nextLine(); System.out.println(search(process(str))); } } } |
原创文章,转载请注明来源:http://euyuil.com/2350/poj-1496-word-index/

打表…哈。AC轻松+愉快啊~
你终于fou头了