原题http://www.patest.cn/contests/pat-a-practise/1078:
The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be “H(key) = key % TSize” where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.
Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.
Input Specification:
Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (<=104) and N (<=MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print “-” instead.
Sample Input:
4 4 10 6 4 15
Sample Output:
0 1 4 -
这个题目主要是两个问题:
- 质数的查找。质数查找采用比较取巧的笨办法,1000以下用质数表,1000以上的用土办法(除以 2~根号X一个个试);
- 哈希表冲突的解决,题目中明确写了使用Quadratic probing(positive increments only),即序号递增的那种二次探测法。具体细节就不多说了,可以参考这里、这里和这里。数据结构荒废多年,自己竟然还要查资料,也是挺不好意思的。
我的代码(c++):
#include <iostream> #include <cmath> using namespace std; int prime_1000[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009 }; int findSmallestPrime_(int biggerThan) { //比1000大的在这边处理 int currNum = biggerThan; while (true) { bool primeFlag = true; for (int n = 2; n <= (int)sqrt(currNum); n++) { if (currNum%n == 0) { primeFlag = false; break; } } if (primeFlag) return currNum; currNum++; } } int findSmallestPrime(int biggerThan) { if (biggerThan < 1000) { // <1000的直接查表 for (int i = 0; i < 169; i++) { if (prime_1000[i] < biggerThan) continue; else return prime_1000[i]; } } else findSmallestPrime_(biggerThan); } int getHashPos(int* hashTable, int Tsize, int val) { //如果塞不进去则返回-1,否则返回位置 //使用Quadratic probing int probIndex = val % Tsize; int H = probIndex; int trialCount = 1; while (hashTable[probIndex] != -1 && trialCount < Tsize) { probIndex = (val + trialCount * trialCount) % Tsize; trialCount++; } if (trialCount >= Tsize) return -1; hashTable[probIndex] = val; return probIndex; } int main() { int M, N; cin >> M >> N; int Tsize = findSmallestPrime(M); int* hashTable = new int[Tsize]; for (int i = 0; i < Tsize; i++) hashTable[i] = -1; for (int i = 0; i < N; i++) { int currVal; cin >> currVal; int pos = getHashPos(hashTable, Tsize, currVal); if (pos == -1) cout << "-"; else cout << pos; if (i < N - 1) cout << " "; } return 0; }
测试点 | 结果 | 用时(ms) | 内存(kB) | 得分/满分 |
---|---|---|---|---|
0 | 答案正确 | 1 | 360 | 12/12 |
1 | 答案正确 | 1 | 360 | 3/3 |
2 | 答案正确 | 1 | 232 | 5/5 |
3 | 答案正确 | 20 | 360 | 5/5 |
最后一个测试点应该是比较大的数