简单搜索poj 2243(水
来源:互联网 发布:淘宝网主要特色 编辑:程序博客网 时间:2024/06/04 19:15
应该也不算一题多解。
就是闲的。。也是因为这题比较简单而且在网上看了别人写的特别好,就想用这题当入门练一下(逃
https://vjudge.net/problem/POJ-2243
题意:
8*8的棋盘,马走斜日,马走几步可以达到给出的终点?
方法一:传统BFS,就不再赘述了,很简单啦。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#define bug cout<<"bugbug"<<endl;using namespace std;char a1,a2,b1,b2;int map[8][8];struct data{ int xi,yi;};int dx[8]={1,2,2,1,-1,-2,-2,-1};int dy[8]={2,1,-1,-2,-2,-1,1,2};int judge(data temp,int x2,int y2){ if(temp.xi==x2&&temp.yi==y2) return 1; return 0;}int bfs(int x1,int y1,int x2,int y2){ memset(map,-1,sizeof(map)); queue<data>que; data in; in.xi=x1; in.yi=y1; que.push(in); map[in.xi][in.yi]=0; while(!que.empty()){ data top,ou; top=que.front(); que.pop(); if(judge(top,x2,y2)) return map[top.xi][top.yi]; for(int i=0;i<8;i++){ ou.xi=top.xi+dx[i]; ou.yi=top.yi+dy[i]; if(map[ou.xi][ou.yi]==-1&&ou.xi>=0&&ou.xi<8&&ou.yi>=0&&ou.yi<8){ que.push(ou); map[ou.xi][ou.yi]=map[top.xi][top.yi]+1; } } } return 0;}int main(){ //freopen("test.txt","r",stdin); while(cin>>a1>>a2>>b1>>b2){ int ans=bfs(a1-'a',a2-'1',b1-'a',b2-'1'); printf("To get from %c%c to %c%c takes %d knight moves.\n",a1,a2,b1,b2,ans); } return 0;}
顺便在这里加一个小技巧。之前有和同学说过这个。
结构体其实是可以和类一样用的。可以非默认构造,如果要非默认构造的话,要记得加一个默认构造函数。
还有一个就是为什么结构体不能放在set啊,map啊里面。
因为set和map的底层是红黑树。红黑树的话他对内部对象就会排序。就要重载一下小于号。自定义一个小于号。
#include <iostream>#include <cstdio>#include <cstring>#include <set>using namespace std;struct data{ int x,y; data(int dx,int dy){ x=dx,y=dy; } data(){} bool operator <(const data b)const{ return x==b.x?x<b.x:y<b.y; }};int main(){ data temp1(1,1); data temp2(2,2); set<data>se; se.insert(temp1); se.insert(temp2); if(se.count(temp1)) cout<<temp1.x<<" "<<temp1.y<<endl; return 0;}
方法二:传统DFS。这个还真的蛮。。。有点小意思吧。而且对这道题的分类也是BFS(hhh分类的人可能是TLE了DFS
我写了一个我认为很对的剪枝其实并没有剪到什么(逃
我还感觉写得蛮对的。结果TLE了两发。。。这我就很不能理解啦。
我一开始DFS函数是这么写的。
void dfs(int x1,int y1,int x2,int y2,int step){ if(judge(x1,y1,x2,y2)){ ans=min(ans,step); return; } if(step>=ans) return;//这就是我说的没什么用的剪枝,发现当前步数(不管找到了没有)比ans大了就直接剪掉。其实也减到了不少,但是对这道题来说确实是。。。嗯。。不够。 for(int i=0;i<8;i++){ int xx=dx[i]+x1; int yy=dy[i]+y1; if(map[xx][yy]==-1&&xx>=0&&xx<8&&yy>=0&&yy<8){ map[xx][yy]=1; dfs(xx,yy,x2,y2,step+1); map[xx][yy]=-1; } }}
超有道理的。对不对。
随后想到,如果我想要剪枝跟有效那我是不是要使ans迅速的变小或者使每一步都能判断出他是否有效。
于是,如果对于一个点 map[x][y]我已经到过这个点,并且我上次到这一点的步数小于这一次的,(这是深搜嘛,广搜就不会遇到这样的问题。)那当前我这条路走下去肯定没有上一次那么走棒,所以我可以对map数组进行更新,使得map数组里的值尽量地小,这样就方便我下一次把它剪掉。
其实也很容易就想到了。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#define bug cout<<"bugbug"<<endl;using namespace std;char a1,a2,b1,b2;int map[8][8];int dx[8]={1,2,2,1,-1,-2,-2,-1};int dy[8]={2,1,-1,-2,-2,-1,1,2};int judge(int x1,int y1,int x2,int y2){ if(x1==x2&&y1==y2) return 1; return 0;}int ans=1e9+7;void dfs(int x1,int y1,int x2,int y2,int step){ if(judge(x1,y1,x2,y2)){ ans=min(ans,step); return; } if(map[x1][y1]==-1||map[x1][y1]>step) map[x1][y1]=step; if(map[x1][y1]<step) return; if(step>=ans) return; for(int i=0;i<8;i++){ int xx=dx[i]+x1; int yy=dy[i]+y1; if(xx>=0&&xx<8&&yy>=0&&yy<8){ dfs(xx,yy,x2,y2,step+1); } }}int main(){ //freopen("test.txt","r",stdin); while(cin>>a1>>a2>>b1>>b2){ memset(map,-1,sizeof(map)); map[a1-'a'][a2-'1']=1; ans=1e9+7; dfs(a1-'a',a2-'1',b1-'a',b2-'1',0); printf("To get from %c%c to %c%c takes %d knight moves.\n",a1,a2,b1,b2,ans); } return 0;}
因为很久没有写搜索了,所以。。。练个手。
这题还有很多种解法,我会陆续写出双向BFS,A*和纯数学解法(感觉很厉害的样子呢)。
- 简单搜索poj 2243(水
- 简单搜索1979@POJ
- poj 3909 简单 搜索
- poj 1166 简单搜索
- poj~1321(简单搜索)
- poj-1321(简单搜索)
- poj 1321 简单搜索
- poj 1979 简单的搜索
- poj 3278 简单的搜索
- POJ 1033-Defragment 简单搜索
- poj 1033 Defragment 简单搜索
- poj 2488 简单的搜索
- POJ-3279(Fliptile)--简单搜索
- poj 2251 简单搜索bfs
- poj 3278 简单搜索bfs
- POJ-----1321搜索简单题
- poj 2243 BFS搜索
- POJ 3126-Prime Path 简单搜索 BFS
- 新的启程,新的进步。
- 33、SQL解析基础
- 《操作系统真象还原》-阅读笔记(中)
- 34、SqlSource解析
- Maven ProfileFilter 分环境运行
- 简单搜索poj 2243(水
- 35、MapperMethod映射器方法.
- mysql之 explain、optimizer_trace 执行计划
- “菜鱼”课设中的一道数据处理的题目(cpp)
- 日常 myeclipse链接VisualSVNServerShell 的错误
- python中多层嵌套列表的拆分
- 1035. 插入与归并(25)
- 记signal和sigaction的一个区别
- Android内存优化大全(中)