POJ3009 Curling 2.0

7 篇文章 0 订阅
7 篇文章 0 订阅

这道题的大概意思就是 一个石头 从起始位置出发 每抛一次算走一步 ,石头只能沿格子的直线滑动 直到遇到一个冰块才停下 当它在冰块面前停下后 这个冰块会消失 求最少需要抛几次 可以让冰块到达终点 

1.起始位置在以后的抛石头过程中也可以滑动 相当于图中的标记为0的位置

2.题中说跑的次数大于10次了就算做游戏失败 这里相当于给搜索做了一个剪枝

3.因为石头每抛一次遇到一块冰块这个冰块就会消失 相当于要一条路走到黑 当前面的路走不下去了返回的时候 原来路上消失的冰块要重新出现 所以 本题我认为还是用深搜做比较好

这道题我做了很长时间 第一开始没考虑全面 用了广搜 导致结果都不对 后来发现了问题 改用了深搜 又因为自己想的过于复杂 不知道哪一步出错了 导致了超时 还有wrong answer 最后还是上网搜了别人的代码来看  有的人的代码很简单 我表示 敬佩啊 并且为自己的智商低感到羞愧

在此推荐 http://www.cnblogs.com/gj-Acit/archive/2013/04/10/3013165.html      http://blog.csdn.net/lyy289065406/article/details/6647671

#include <stdio.h>
#include <string.h>
int ex,ey,sx,sy;
int w,h;
int step,min;
int map[25][25];
int vir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int judge(int x,int y)
{
	if(x>0&&x<=h&&y>0&&y<=w&&map[x][y]!=1)
	return 1;
	else
	{
		return 0;
	}
}
void dfs(int x,int y)
{
	int i;
	if(step>10)
	return ;//据说这是剪枝 题中说大于10歩 算作游戏失败 
	for(i=0;i<4;i++)
	{
		int nx,ny;
		int ok=0;
		nx=x+vir[i][0];
		ny=y+vir[i][1];
		while(judge(nx,ny))
		{
			ok=1;
			if(nx==ex&&ny==ey)
			{
				if(step<min)
				{
					min=step;
					return ;
				}
			}
			nx=nx+vir[i][0];
			ny=ny+vir[i][1];
		}
		if(map[nx][ny]==1&&ok)
		{
			map[nx][ny]=0;step++;
			dfs(nx-vir[i][0],ny-vir[i][1]);
			map[nx][ny]=1;step--;
		}
	}
}
int  main()
{
	while(~scanf("%d%d",&w,&h)&&w&&h)//w为列 h为宽 
	{
		memset(map,-1,sizeof(map)); //有边界控制 可以不每次都初始化 
		for(int i=1;i<=h;i++)
		{
			for(int j=1;j<=w;j++)
			{
				scanf("%d",&map[i][j]);
				if(map[i][j]==2)
				{
					sx=i;
					sy=j;
				}
				if(map[i][j]==3)
				{
					ex=i;
					ey=j;
				}
			}
		}
		min=1000000;
		step=1;//记得步子初始化为1 可以仔细想想是为什么 跟着题中的例子走一次即可 
		dfs(sx,sy);
		if(min>10)
		{
			printf("-1\n");
		}
		else
		{
			printf("%d\n",min);
		}
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值