Problem D Knights in FEN
Input: standard input Output: standard output Time Limit: 10 seconds
解题思路:
这题完全照搬刘汝佳书里的思想,感觉照搬他的代码对自己来说感到真心的别扭,极力的希望想在里面找到点值得学习的东西,真心去发现还是能学到不少东西的,比如说用“引用”简化代码,不屈于题目的情景而用一维数组表示二维的内容,不知道这样能不能锻炼到自己的思维,有时几天没做题或当时一题卡你几天真心急了的时候,就会忘记做题的初衷是什么了,就像这次,开始并没有用哈希查找,直接就线性遍历查看有无重复情况出现,后来发现不是一般的慢啊!一个一个输出查看的时候感觉不是很慢,但如果等到移动的步数到10的时候就超过了一分钟了,接着想自己处理一下一些特殊的情况,也就是将移动的步数为9和10的不再放入到队列里面(不进行广度查找)发现还是很难改变现状。无奈后来用了书里介绍的STL中的set结构后,发现效率增加了不少啊!这时发现很多事情都是由细节所决定的,往往一件小事看不出什么问题,但如果量变到了一定的时候,那么效果就出来了
题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=110&page=show_problem&problem=1363
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<set> 5 #define NUM 10000000 6 using namespace std; 7 typedef int State[25]; 8 State st[NUM], temp, source, goal = {1,1,1,1,1,0,1,1,1,1,0,0,-1,1,1,0,0,0,0,1,0,0,0,0,0}; 9 int dist[NUM], head[NUM], next[NUM]; 10 int dir[8][2] = {{-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}}; 11 set<int> vis; 12 13 int try_to_insert(int s) 14 { 15 int v=0; 16 for(int i=0;i<25;i++) v=v*2+st[s][i]; 17 v=v*2+1; 18 if(vis.count(v)) return 0; 19 vis.insert(v); 20 return 1; 21 } 22 23 int Traverse() 24 { 25 vis.clear(); 26 int front, rear, i, j, x, y, blank, z, d, flag, k, newx, newy; 27 front = 1, rear = 2; 28 while(front<rear) 29 { 30 for(blank=0; blank<25 && st[front][blank] != -1; ++blank); 31 if(memcmp(goal, st[front], sizeof(State)) == 0) return front; 32 x = blank/5, y = blank%5; 33 for(d=0; d<8; ++d) 34 { 35 i = x+dir[d][0]; 36 j = y+dir[d][1]; 37 z = i*5+j; 38 if(i>=0 && i<5 && j>=0 && j<5) 39 { 40 memcpy(st[rear], st[front], sizeof(State)); 41 st[rear][z] = st[front][blank]; 42 st[rear][blank] = st[front][z]; 43 dist[rear] = dist[front] + 1; 44 if(try_to_insert(rear) && dist[rear] < 11) 45 { 46 if(dist[rear] == 10 && memcmp(goal, st[rear], sizeof(State)) == 0) return rear; 47 rear++; 48 } 49 } 50 } 51 front++; 52 } 53 return 0; 54 } 55 56 57 int main() 58 { 59 #ifndef ONLINE_JUDGE 60 freopen("input.txt", "r", stdin); 61 #endif 62 63 int i, j, N, ans, cnt=0; 64 char input; 65 scanf("%d", &N); 66 while(N--) 67 { 68 getchar(); 69 for(cnt=0; cnt<25;) 70 { 71 scanf("%c", &input); 72 switch(input) 73 { 74 case '1': st[1][cnt++] = 1; break; 75 case '0': st[1][cnt++] = 0; break; 76 case ' ': st[1][cnt++] = -1; break; 77 } 78 } 79 memset(dist, 0, sizeof(dist)); 80 ans = 0; 81 ans = Traverse(); 82 if(ans == 0) printf("Unsolvable in less than 11 move(s).\n"); 83 else printf("Solvable in %d move(s).\n", dist[ans]); 84 } 85 return 0; 86 }