POJ 1945 Power Hungry Cows
Posted in PKU OJ on 五月 18th, 2010 by 纳米 – 2 Comments2010-05-17,阅读题目,Code
2010-05-18,BFS重写,本地测试,爆数组,AC,改非HASH,AC
解题报告:
本来这道题在推荐列表里面是IDA*的。但是我确实不会写启发函数,然后,随便写了个迭代加深严重超时。还是BFS了吧~
扩展状态,把两个变量(wv0, wv1)作为一个整体,不断扩展扩展,可以得到以下代码1中Line63 – Line69的8组新状态。注意保证wv0 > wv1。这样做会MLE和TLE的。用了一种恶心的方法,假定wv1很小,就给定一个很小的数,大于这个数不扩展就好了。正确性不知道,反正把数据过了。开始我写了个HASH的,还写了个指针的指针,第一次写呢。后来发现用了上面那个技巧连HASH都不用。我还是把2份代码都贴出来了。
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 | #include <stdio.h> const int maxn = 20003, maxq = 400003, prime0 = 20011, prime1 = 97; int n, n2, answer, head, last, q[maxq][3]; struct HASH { int wv0, wv1; HASH *next; } *hash[prime0][prime1]; int input() { scanf("%d", &n); return 0; } bool in_hash(int wv0, int wv1) { int p0 = wv0 >= prime0 ? wv0 % prime0 : wv0; int p1 = wv1 >= prime1 ? wv1 % prime1 : wv1; HASH *t = hash[p0][p1]; while (t != NULL && (t->wv0 != wv0 || t->wv1 != wv1)) t = t->next; return t != NULL; } void add_hash(int wv0, int wv1) { int p0 = wv0 >= prime0 ? wv0 % prime0 : wv0; int p1 = wv1 >= prime1 ? wv1 % prime1 : wv1; HASH **t = &hash[p0][p1]; while (*t != NULL) t = &((*t)->next); *t = new HASH; (*t)->wv0 = wv0, (*t)->wv1 = wv1; (*t)->next = NULL; } bool add_node(int wv0, int wv1, int step) { if (wv0 == n || wv1 == n) return true; if (wv0 < wv1) { int temp = wv0; wv0 = wv1; wv1 = temp; } if (wv0 == wv1 || wv0 >= n2 || wv1 >= prime1) return false; if (!in_hash(wv0, wv1)) { add_hash(wv0, wv1); ++last; q[last][0] = wv0; q[last][1] = wv1; q[last][2] = step; } return false; } int work() { n2 = n << 1; head = last = -1; add_node(1, 0, 0); while (head < last) { ++head; int wv0 = q[head][0], wv1 = q[head][1], step1 = q[head][2] + 1; if ( add_node(wv0+wv0, wv1, step1) || add_node(wv0+wv1, wv1, step1) || add_node(wv1+wv1, wv1, step1) || add_node(wv0, wv0+wv0, step1) || add_node(wv0, wv0+wv1, step1) || add_node(wv0, wv1+wv1, step1) || add_node(wv0, wv0-wv1, step1) || add_node(wv0-wv1, wv0, step1)) { answer = step1; break; } } return 0; } int output() { printf("%d\n", answer); return 0; } int main() { input(); work(); output(); return 0; } |
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 | #include <stdio.h> const int maxn = 20003, maxq = 700003, prime0 = 20101, prime1 = 97; int n, n2, answer, head, last, q[maxq][3]; bool hash[prime0][prime1]; int input() { scanf("%d", &n); return 0; } bool in_hash(int wv0, int wv1) { return hash[wv0][wv1]; } void add_hash(int wv0, int wv1) { hash[wv0][wv1] = true; } bool add_node(int wv0, int wv1, int step) { if (wv0 == n || wv1 == n) return true; if (wv0 < wv1) { int temp = wv0; wv0 = wv1; wv1 = temp; } if (wv0 == wv1 || wv0 >= n2 || wv1 >= prime1) return false; if (!in_hash(wv0, wv1)) { add_hash(wv0, wv1); ++last; q[last][0] = wv0; q[last][1] = wv1; q[last][2] = step; } return false; } int work() { n2 = n + prime1; head = last = -1; add_node(1, 0, 0); while (head < last) { ++head; int wv0 = q[head][0], wv1 = q[head][1], step1 = q[head][2] + 1; if ( add_node(wv0+wv0, wv1, step1) || add_node(wv0+wv1, wv1, step1) || add_node(wv1+wv1, wv1, step1) || add_node(wv0, wv0+wv0, step1) || add_node(wv0, wv0+wv1, step1) || add_node(wv0, wv1+wv1, step1) || add_node(wv0, wv0-wv1, step1) || add_node(wv0-wv1, wv0, step1)) { answer = step1; break; } } return 0; } int output() { printf("%d\n", answer); return 0; } int main() { input(); work(); output(); return 0; } |