【POJ3009 - Curling】 解题报告+思路+代码+教训(看别人的报告过的)
2012-03-11 23:15
507 查看
#include <cstring> #include <cstdlib> #include <cstdio> #include <iostream> #define INPUT /** Problem : poj3009 看别人的报告过得,代码基本上相同,因为实在不会了 Begin Time: 11th/3/2012 7:28 p.m. End Time: 11th/3/2012 11:10 p.m. 解题报告:http://blog.csdn.net/harder2005/article/details/2816881 测试数据见Discuss 知识点: DFS,回溯,智商!! 教训: 这道题十分经典,简直是“不动脑子就WA”的一道题的典范 解题报告中的代码十分简洁精练,十分推荐!! 1.关于搜索的选择 虽然是最短,但是题中说了超过10次就失败,所以暗示了使用DFS 这点跟那个Nightmare的思路是一样的 2.关于智商 这道题中有一个Block,解题报告里面把Block看做了是墙,但是如果判断 没有出maze,那么maze[i][j] == 1.回溯的时候maze[i][j] == 0 3.关于输入输出 这道题解题报告十分经典的一个原因,就是mazi[i][j] = 1(能够通过) maze[i][j] = 0不能通过,这跟WY学长提到的memset不能设1 (否则内存变成1111111111111111)思想是一样的 4.关于搜索 这道题说冰壶丢出去就要一直碰到Block才停下,所以有一个 while(maze[i][j]) tmp.x++.... 在+完之后tmp.x--,然后判断tmp.x + 1是否在范围内,来判断是否扔出了范围 这点很赞 5.关于回溯 这题作者把_min设置为了11,最多也就是11层,判断每个节点p > _min的时候就回溯! 既保证了最优解,又保证了剪枝,这个思想非常赞啊 思路大概就是,每次撞墙判断是否在范围内,如果在范围内那就对应的墙为1(可以通过),然后 继续搜索,每次搜索到了Goal就_min = min (_min,tmp.p); 而且,这道题扔出去了就搜索其他方向的思路(用了四个while循环)和其他的搜索模板给出 向量direct[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };的思路不一样 太赞了,简直是可以作为一个新模板,一定要好好做 */ using namespace std; const int c0de4fun = 30; int maze[c0de4fun][c0de4fun]; struct Node { int x,y,p; }; Node pb,pe; //point of Begin,point of End; int _min; int W,H,tmp; void DFS(Node nod) { Node tmp,tmp1; tmp = nod; if ( tmp.x == pe.x && tmp.y == pe.y ) { if ( _min > tmp.p ) { _min = tmp.p; } return; ///找到更优解就回溯 } if ( tmp.p + 1 > _min ) return ; ///这个回溯剪枝是一个Punch Point! tmp1 = tmp; while(maze[tmp1.x][tmp1.y]) { tmp1.x++; if( tmp1.x == pe.x && tmp1.y == pe.y) { if ( tmp1.p + 1 < _min) { _min = tmp1.p + 1; } return; } } tmp1.x--; ///撞墙了 if ( tmp1.x + 1 <= H && tmp1.x != tmp.x) { ///没有越界 ///发生过移动 tmp1.p = tmp.p + 1; maze[tmp1.x+1][tmp1.y] = 1; DFS(tmp1); maze[tmp1.x+1][tmp1.y] = 0; //回溯 } tmp1 = tmp; while(maze[tmp1.x][tmp1.y]) { tmp1.y++; if( tmp1.x == pe.x && tmp1.y == pe.y) { if ( tmp1.p + 1 < _min) { _min = tmp1.p + 1; } return; } } tmp1.y--; ///撞墙了 if ( tmp1.y + 1 <= W && tmp1.y != tmp.y) { ///没有越界 ///发生过移动 tmp1.p = tmp.p + 1; maze[tmp1.x][tmp1.y+1] = 1; DFS(tmp1); maze[tmp1.x][tmp1.y+1] = 0; //回溯 } tmp1 = tmp; while(maze[tmp1.x][tmp1.y]) { tmp1.x--; if( tmp1.x == pe.x && tmp1.y == pe.y) { if ( tmp1.p + 1 < _min) { _min = tmp1.p + 1; } return; } } tmp1.x++; ///撞墙了 if ( tmp1.x - 1 > 0 && tmp1.x != tmp.x) { ///没有越界 ///发生过移动 tmp1.p = tmp.p + 1; maze[tmp1.x-1][tmp1.y] = 1; DFS(tmp1); maze[tmp1.x-1][tmp1.y] = 0; //回溯 } tmp1 = tmp; while(maze[tmp1.x][tmp1.y]) { tmp1.y--; if( tmp1.x == pe.x && tmp1.y == pe.y) { if ( tmp1.p + 1 < _min) { _min = tmp1.p + 1; } return; } } tmp1.y++; ///撞墙了 if ( tmp1.y - 1 > 0 && tmp1.y != tmp.y) { ///没有越界 ///发生过移动 tmp1.p = tmp.p + 1; maze[tmp1.x][tmp1.y-1] = 1; DFS(tmp1); maze[tmp1.x][tmp1.y-1] = 0; //回溯 } } int main() { #ifdef INPUT freopen("b:\\acm\\poj3009\\input.txt","r",stdin); #endif while ( scanf("%d%d",&W,&H) != EOF && W != 0 && H != 0) { tmp = 0; memset(maze,0,sizeof(int)*c0de4fun*c0de4fun); _min = 11; for( int i = 1 ; i <= H ; i++) { for( int j = 1 ; j<= W; j++) { scanf("%d",&tmp); maze[i][j] = 1; if ( tmp == 1 ) { maze[i][j] = 0; } if ( tmp == 3 ) { pe.x = i; pe.y = j; } if ( tmp == 2 ) { pb.x = i; pb.y = j; pb.p = 0; } } } DFS(pb); if( _min <= 10 ) { printf("%d\n",_min); } else { printf("-1\n"); } } return 0; }
相关文章推荐
- 【HDU1272】小希的迷宫解题报告,数据+思路+代码
- 【HDU1072】Nightmare,思路+解题报告+代码
- 【POJ3740】Easy Finding,解题报告+思路+代码
- 【poj1164】The Castle,解题报告+思路+代码+数据
- 【HDU3415】Max Sum of Max-K-sub-sequence,思路+解题报告+AC代码+自虐般疯狂吐槽【0.3%达成!】
- 【HDU1686】Oulipo 思路+解题报告+代码+KMP算法个人理解 【0.5%达成】
- 【POJ2255】Tree Recovery解题报告 思路 + 数据 +代码
- 【HDU4313】 - Matrix - 树状DP Version 思路+解题报告+AC代码【0.4%达成】
- 【POJ1182】食物链,思路+数据+代码,可能是史上关于这道题最详细的解题报告
- 【HDU2780 - Su-Su-Sudoku】 解题报告+思路+代码,差点一次AC T^T
- 【POJ1077】Eight 八数码问题,解题报告+思路+代码
- 【0.9%】SPOJ7758 Grwoing Strings 解题报告 + AC代码 + 思路 + AC自动机简短总结
- 【POJ2488】 A knight's Journey 解题报告 测试数据+代码+思路
- 【POJ1011 Sticks】解题报告+思路+代码
- 【HDU4313】Matrix 多校 解题报告+AC代码+思路+算法正确性证明,此为Kruskal贪心简单版本,恶心版本稍后放出【目标达成 0.2%】
- 【HDU4313】Matrix 多校 解题报告+AC代码+思路+算法正确性证明,此为Kruskal贪心恶心版本,非自虐倾向慎入!建议想找解题报告的童鞋看简单版本的,这个我写给自己【目标达成 0.2%】
- 【UVa10167】 Birthday Cake,思路+代码+解题报告
- 【ZOJ1649 Rescue】 解题报告+代码+思路
- 参考了别人的暴力代码 自己的错误在与 思路并不复杂 但是自己的map并没有请空 这个错误 要改
- hdu 1253 胜利大逃亡 (代码详解)解题报告