poj3009
来源:互联网 发布:大尺度网络电影 编辑:程序博客网 时间:2024/04/27 14:45
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int w,h,sx,sy,ex,ey,maze[25][25],ans,
dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
void dfs(int x,int y,int step) //step作为参数
{
if (step>10||step>ans) return; //结束条件
for (int i=0;i<4;i++) //穷举所有可能
{
int xx=x,yy=y;
while (1)
{
xx+=dx[i];yy+=dy[i]; //一步一步走
if (xx<1||xx>h||yy<1||y>w) break; //越界不符合条件,换一个方向
if (xx==ex&&yy==ey) //到终点
{
step++;
if (step<ans) ans=step; //记录最小值
return; //回到上一层dfs
}
else if (maze[xx][yy]==1) //遇到障碍
{
if (xx-dx[i]!=x||yy-dy[i]!=y) //若xx-dx[i]==x&&yy-dy[i]==y,说明从静止时开始走的第一步就遇到障碍,
//此时该方向不能走,障碍也不会消失,障碍只有在方块运动时撞击才会消失
{
maze[xx][yy]=0; //消去方块
dfs(xx-dx[i],yy-dy[i],step+1); //dfs
maze[xx][yy]=1; //还原方块
}
break; //遇到障碍则该方向结束
}
}
}
}
/*void dfs(int x,int y) //step作为全局变量,初始化为0
{
if (step>=10) return;
for (int i=0;i<4;i++)
{
int xx=x,yy=y;
while (1)
{
xx+=dx[i];yy+=dy[i];
if (xx<1||xx>h||yy<1||y>w) break;
if (xx==ex&&yy==ey)
{
step++;
if (step<ans) ans=step;
step--; //还原step,再回到上一层dfs
return;
}
else if (maze[xx][yy]==1)
{
if (xx-dx[i]!=x||yy-dy[i]!=y)
{
maze[xx][yy]=0;
step++;
dfs(xx-dx[i],yy-dy[i]);
step--; //还原step,
maze[xx][yy]=1;
}
break;
}
}
}
}
*/
int main()
{
freopen("in.txt","r",stdin);
cin>>w>>h;
while (w+h!=0)
{
memset(maze,0,sizeof(maze)); //一定要全部初始化!!!!!
for (int i=1;i<=h;i++)
for (int j=1;j<=w;j++)
{
cin>>maze[i][j];
if (maze[i][j]==2) {sx=i;sy=j;}
if (maze[i][j]==3) {ex=i;ey=j;}
}
ans=15;
dfs(sx,sy,0);
if (ans<=10) cout<<ans<<endl;else cout<<"-1"<<endl;
cin>>w>>h;
}
return 0;
}
/*题意:搜索,已知起点和终点,求石子从起点到达终点的最短路,如果无法到达,则输出-1。石子移动的具体规则如下:
1、开始时,石子在起点s处
2、运动方向可以是水平或垂直的,不能斜方向运动
3、最开始的时候,你可以将石子向上下左右任意一个方向抛,如果与它相邻的点是障碍物的话除外
4、一旦石子开始运动,有三种可能:
a、遇到障碍物,石子会停在障碍物的前一格,障碍物会消失
b、如果出界,游戏失败
c、到达终点,游戏结束并成功
5、如果移动的次数超过10次,将认为游戏是失败的
算法:dfs求最短路,因为障碍会消失,bfs无法保存状态*/
#include <stdio.h>
#include <cstring>
using namespace std;
int w,h,sx,sy,ex,ey,maze[25][25],ans,
dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
void dfs(int x,int y,int step) //step作为参数
{
if (step>10||step>ans) return; //结束条件
for (int i=0;i<4;i++) //穷举所有可能
{
int xx=x,yy=y;
while (1)
{
xx+=dx[i];yy+=dy[i]; //一步一步走
if (xx<1||xx>h||yy<1||y>w) break; //越界不符合条件,换一个方向
if (xx==ex&&yy==ey) //到终点
{
step++;
if (step<ans) ans=step; //记录最小值
return; //回到上一层dfs
}
else if (maze[xx][yy]==1) //遇到障碍
{
if (xx-dx[i]!=x||yy-dy[i]!=y) //若xx-dx[i]==x&&yy-dy[i]==y,说明从静止时开始走的第一步就遇到障碍,
//此时该方向不能走,障碍也不会消失,障碍只有在方块运动时撞击才会消失
{
maze[xx][yy]=0; //消去方块
dfs(xx-dx[i],yy-dy[i],step+1); //dfs
maze[xx][yy]=1; //还原方块
}
break; //遇到障碍则该方向结束
}
}
}
}
/*void dfs(int x,int y) //step作为全局变量,初始化为0
{
if (step>=10) return;
for (int i=0;i<4;i++)
{
int xx=x,yy=y;
while (1)
{
xx+=dx[i];yy+=dy[i];
if (xx<1||xx>h||yy<1||y>w) break;
if (xx==ex&&yy==ey)
{
step++;
if (step<ans) ans=step;
step--; //还原step,再回到上一层dfs
return;
}
else if (maze[xx][yy]==1)
{
if (xx-dx[i]!=x||yy-dy[i]!=y)
{
maze[xx][yy]=0;
step++;
dfs(xx-dx[i],yy-dy[i]);
step--; //还原step,
maze[xx][yy]=1;
}
break;
}
}
}
}
*/
int main()
{
freopen("in.txt","r",stdin);
cin>>w>>h;
while (w+h!=0)
{
memset(maze,0,sizeof(maze)); //一定要全部初始化!!!!!
for (int i=1;i<=h;i++)
for (int j=1;j<=w;j++)
{
cin>>maze[i][j];
if (maze[i][j]==2) {sx=i;sy=j;}
if (maze[i][j]==3) {ex=i;ey=j;}
}
ans=15;
dfs(sx,sy,0);
if (ans<=10) cout<<ans<<endl;else cout<<"-1"<<endl;
cin>>w>>h;
}
return 0;
}
/*题意:搜索,已知起点和终点,求石子从起点到达终点的最短路,如果无法到达,则输出-1。石子移动的具体规则如下:
1、开始时,石子在起点s处
2、运动方向可以是水平或垂直的,不能斜方向运动
3、最开始的时候,你可以将石子向上下左右任意一个方向抛,如果与它相邻的点是障碍物的话除外
4、一旦石子开始运动,有三种可能:
a、遇到障碍物,石子会停在障碍物的前一格,障碍物会消失
b、如果出界,游戏失败
c、到达终点,游戏结束并成功
5、如果移动的次数超过10次,将认为游戏是失败的
算法:dfs求最短路,因为障碍会消失,bfs无法保存状态*/
0 0
- poj3009
- POJ3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- poj3009
- POJ3009
- poj3009(dfs)
- DFS poj3009
- poj3009 冰球
- POJ3009-DFS
- POJ3009 dfs
- 2014134029于庆龄
- poj1979
- Java基础知识总结(数组)
- Can't connect to VPN on Fedora 21
- Javascrpt无刷新文件上传
- poj3009
- Base64
- arguments实参集合与局部变量,参数关系
- Ubuntu Linux中开启MySQL远程访问功能
- Android 模拟圆形水杯倒水的效果
- poj3669
- 将Rsyslog的日志输出到Kafka消息队列
- BZOJ 1452 [JSOI2009]Count 二维树状数组
- poj3126