http://poj.org/problem?id=3083
2013-07-24 12:57
253 查看
这算是poj上搜索中的水题!这只是在大部分人来讲吧!!对于我这样的菜鸟级的,哎,,还是参考了下别人打代码,才有点思路!其实这题仔细想过之后其实不难。
对于这道题首先我并非一点都不会,只是有一个地方不太会,就是选择方向上,就是左优先,和右优先。主要问题出在还不太会判断具体左右各自优先时,该怎样判断其方向。其实问题在我看过别人的解题思路之后,还是比较简单的。画个正方形,顺时钟就是向右优先,逆时针就是向左优先。还有一个问题就是具体在操作时该如何确定搜索方向的!
这里我还是有的不太理解。还在进一步思索中!向左向右其实用到深搜就可以解决,但是第三问就是要用到广搜了。我的问题而主要出现在对于深搜的具体操作时,该如何判断方向!具体请看代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N=45;
char map
;
int dirl[4][2]= /*{{0,-1},{1,0},{0,1},{-1,0}};*/{{1,0},{0,1},{-1,0},{0,-1}};//还有就是这里的方向不可以乱,必须是顺时针,或逆时针。否则运行会有问题!
int dirr[4][2]= /*{{0,1},{1,0},{0,-1},{-1,0}};*/{{-1,0},{0,1},{1,0},{0,-1}};
bool flag
;
int h,w,dl,dr;
int star[2],end[2];
struct point
{
int x;
int y;
int step;
};
void init()
{
int i,j;
}
int dfs(int s,int e,int d,int dir[][2])
{
int step,t,x1,y1;
if(s==end[0]&&e==end[1])
{
return 1;
}
for(int i=0; i<4; i++)
{
t=(d+i)%4; //这里是尤其要注意的,这里是确定搜索具体怎样执行方向的!
x1=s+dir[t][1];
y1=e+dir[t][0];
if(x1>=0&&x1<w&&y1>=0&&y1<h&&!flag[x1][y1])
break;
}
step=dfs(x1,y1,(t+3)%4,dir)+1; //这里也是需要注意的地方。。
return step;
}
int bfs() //广搜就不要说了,最简单的广搜!
{
queue<point>Q;
memset(flag,false,sizeof(flag));
point last,next;
last.x=star[0];
last.y=star[1];
last.step=1;
flag[last.x][last.y]=true;
Q.push(last);
while(!Q.empty())
{
last=Q.front();
Q.pop();
if(last.x==end[0]&&last.y==end[1])
{
return last.step;
}
for(int i=0; i<4; i++)
{
next.x=last.x+dirl[i][1];
next.y=last.y+dirl[i][0];
if(next.x>=0&&next.x<w&&next.y>=0&&next.y<h&&map[next.x][next.y]!='#'&&!flag[next.x][next.y])
{
flag[next.x][next.y]=true;
next.step=last.step+1;
Q.push(next);
}
}
}
return 0;
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&h,&w);
memset(flag,false,sizeof(flag));
for(i=0; i<w; i++)
{
for(j=0; j<h; j++)
{
cin>>map[i][j];
if(map[i][j]=='#')
{
flag[i][j]=true;
}
else if(map[i][j]=='S')
{
star[0]=i;
star[1]=j;
}
else if(map[i][j]=='E')
{
end[0]=i;
end[1]=j;
}
}
}//因为根据题意 可知道s 与E 都在靠近最外层
if(star[0]==0) //在最上层。
{
dl=1; //这里的数字主要是确定搜索的方向,而设的!
dr=1;
}
else if(star[0]==h-1) //在最下层
{
dl=3;
dr=3;
}
else if(star[1]==w-1)//在最后一列
{
dl=2;
dr=0;
}
else //在第一列
{
dl=0;
dr=2;
}
printf("%d ",dfs(star[0],star[1],dl,dirl));
printf("%d ",dfs(star[0],star[1],dr,dirr));
printf("%d\n",bfs());
}
return 0;
}
对于这道题首先我并非一点都不会,只是有一个地方不太会,就是选择方向上,就是左优先,和右优先。主要问题出在还不太会判断具体左右各自优先时,该怎样判断其方向。其实问题在我看过别人的解题思路之后,还是比较简单的。画个正方形,顺时钟就是向右优先,逆时针就是向左优先。还有一个问题就是具体在操作时该如何确定搜索方向的!
这里我还是有的不太理解。还在进一步思索中!向左向右其实用到深搜就可以解决,但是第三问就是要用到广搜了。我的问题而主要出现在对于深搜的具体操作时,该如何判断方向!具体请看代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N=45;
char map
;
int dirl[4][2]= /*{{0,-1},{1,0},{0,1},{-1,0}};*/{{1,0},{0,1},{-1,0},{0,-1}};//还有就是这里的方向不可以乱,必须是顺时针,或逆时针。否则运行会有问题!
int dirr[4][2]= /*{{0,1},{1,0},{0,-1},{-1,0}};*/{{-1,0},{0,1},{1,0},{0,-1}};
bool flag
;
int h,w,dl,dr;
int star[2],end[2];
struct point
{
int x;
int y;
int step;
};
void init()
{
int i,j;
}
int dfs(int s,int e,int d,int dir[][2])
{
int step,t,x1,y1;
if(s==end[0]&&e==end[1])
{
return 1;
}
for(int i=0; i<4; i++)
{
t=(d+i)%4; //这里是尤其要注意的,这里是确定搜索具体怎样执行方向的!
x1=s+dir[t][1];
y1=e+dir[t][0];
if(x1>=0&&x1<w&&y1>=0&&y1<h&&!flag[x1][y1])
break;
}
step=dfs(x1,y1,(t+3)%4,dir)+1; //这里也是需要注意的地方。。
return step;
}
int bfs() //广搜就不要说了,最简单的广搜!
{
queue<point>Q;
memset(flag,false,sizeof(flag));
point last,next;
last.x=star[0];
last.y=star[1];
last.step=1;
flag[last.x][last.y]=true;
Q.push(last);
while(!Q.empty())
{
last=Q.front();
Q.pop();
if(last.x==end[0]&&last.y==end[1])
{
return last.step;
}
for(int i=0; i<4; i++)
{
next.x=last.x+dirl[i][1];
next.y=last.y+dirl[i][0];
if(next.x>=0&&next.x<w&&next.y>=0&&next.y<h&&map[next.x][next.y]!='#'&&!flag[next.x][next.y])
{
flag[next.x][next.y]=true;
next.step=last.step+1;
Q.push(next);
}
}
}
return 0;
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&h,&w);
memset(flag,false,sizeof(flag));
for(i=0; i<w; i++)
{
for(j=0; j<h; j++)
{
cin>>map[i][j];
if(map[i][j]=='#')
{
flag[i][j]=true;
}
else if(map[i][j]=='S')
{
star[0]=i;
star[1]=j;
}
else if(map[i][j]=='E')
{
end[0]=i;
end[1]=j;
}
}
}//因为根据题意 可知道s 与E 都在靠近最外层
if(star[0]==0) //在最上层。
{
dl=1; //这里的数字主要是确定搜索的方向,而设的!
dr=1;
}
else if(star[0]==h-1) //在最下层
{
dl=3;
dr=3;
}
else if(star[1]==w-1)//在最后一列
{
dl=2;
dr=0;
}
else //在第一列
{
dl=0;
dr=2;
}
printf("%d ",dfs(star[0],star[1],dl,dirl));
printf("%d ",dfs(star[0],star[1],dr,dirr));
printf("%d\n",bfs());
}
return 0;
}
相关文章推荐
- http://poj.org/problem?id=2251
- http://poj.org/problem?id=3337
- http://poj.org/problem?id=1503
- http://poj.org/problem?id=3125
- http://poj.org/problem?id=1135
- http://poj.org/problem?id=1486
- http://poj.org/problem?id=2728&&最优比例生成树
- (博客搬迁啦)pku1276多重背包问题(http://poj.org/problem?id=1276)
- Dungeon Master&&http://poj.org/problem?id=2251
- 贪心+乱搞——最高的牛http://poj.org/problem?id=3263
- http://poj.org/problem?id=1840
- http://poj.org/problem?id=1125
- http://poj.org/problem?id=1975&&同上
- http://poj.org/problem?id=1258
- http://poj.org/problem?id=3259
- http://poj.org/problem?id=2607&&最短路
- poj 1088 滑雪问题http://poj.org/problem?id=1088
- http://poj.org/problem?id=3264
- http://poj.org/problem?id=2299 树状数组 《复习》
- http://poj.org/problem?id=2503&&hash