poj3009Curling 2.0(打冰球,DFS)

题意:要求把一个冰壶从起点“2”用最少的步数移动到终点“3”,其中0为移动区域,1为石头区域,冰壶一旦想着某个方向运动就不会停止,也不会改变方向(想想冰壶在冰上滑动),除非冰壶撞到石头1或者到达终点3,(冰球到达边界会滑出去,不会反弹回来)冰壶撞到石头后,冰壶会停在石头前面,此时(静止状态)才允许改变冰壶的运动方向,而该块石头会破裂,石头所在的区域由1变为0. 也就是说,冰壶撞到石头后,并不会取代石头的位置。输出 2 到 3 的最小移动次数。如果移动次数大于10次,或者冰球滑出去了,输出  -1 。

自己WA了好多次,其实就是不细心,下面贴出WA的数据

输入:

5 4
1 1 2 1 1
1 0 0 0 0
1 0 0 1 3
1 1 1 1 1

输出

4

输入

20 20
0 1 0 0 0 0 1 0 1 0 0 1 0 2 0 1 0 1 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1
0 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 1
0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1
0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 1
1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1
1 1 0 0 0 0 0 1 0 0 0 0 0 0 3 0 1 0 0 0
0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0
1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 1 0 0
0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0
1 0 1 0 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 0
0 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 0 1 0 0
0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1
1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0
0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 1 1 1
1 1 0 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 0 1
0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1
1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 1

输出

5

输入

5 2
2 0 1 1 1
0 0 1 1 3
7 7
0 0 0 0 2 0 0
0 0 1 0 0 0 0
0 0 0 0 0 1 1
0 1 0 0 0 0 0 
0 0 0 0 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 3 0
10 10
1 1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 0 1 1
2 1 0 1 1 1 1 1 1 1
1 1 1 1 1 1 0 1 1 1
1 0 1 0 1 1 1 1 1 1 
1 1 1 1 1 3 1 0 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 1
1 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1

输出

-1
6
9

 

很垃圾很啰嗦的代码

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int w, h;
int a[25][25];
int sx, sy;
int ans;
void dfs(int x, int y, int num){
	if (num >= 10)return;
	int flag = 0;
	int tag = 0;
	int i;
	//to left
	if (y > 0&&y<w){
		for (i = y-1; i >= 0; i--){
			if (a[x][i] == 1){
				tag = 1;
				break;
			}
			else if (a[x][i] == 3){
				num++;
				ans = ans < num ? ans : num;
				//printf("sx=%d sy=%d x=%d y=%d ans=%d  num=%d\n", sx, sy, x, y, ans, num);
				return;
			}
			else if(a[x][i]==0)flag = 1;
		}
		if (flag){
			if (tag){
				a[x][i] = 0;
				dfs(x, i + 1, num + 1);
				a[x][i] = 1;
			}
			
		}
		
	}
	//to right
	flag = 0, tag = 0;
	if (y < w-1&&y>=0){
		for (i = y + 1; i<=w-1; i++){
			if (a[x][i] == 1){
				tag = 1;
				break;
			}
			else if (a[x][i] == 3){
				num++;
				ans = ans < num ? ans : num;
				//printf("sx=%d sy=%d x=%d y=%d ans=%d  num=%d\n", sx, sy, x, y, ans, num);
				return;
			}
			else if (a[x][i] == 0)flag = 1;
		}
		if (flag){
			if (tag){
				a[x][i] = 0;
				dfs(x, i - 1, num + 1);
				a[x][i] = 1;
			}
			
		}
		
	}
	//to up
	flag = 0, tag = 0;
	if (x > 0&&x<h){
		for (i = x - 1; i >= 0; i--){
			if (a[i][y] == 1){
				tag = 1;
				break;
			}
			else if (a[i][y] == 3){
				num++;
				ans = ans < num ? ans : num;
				//printf("sx=%d sy=%d x=%d y=%d ans=%d  num=%d\n", sx, sy, x, y, ans, num);
				return;
			}
			else if (a[i][y] == 0)flag = 1;
		}
		if (flag){
			if (tag){
				a[i][y] = 0;
				dfs(i+1, y, num + 1);
				a[i][y] = 1;
			}
			
		}
		
	}
	//to down
	flag = 0, tag = 0;
	if (x < h&&x>=0){
		for (i = x + 1; i< h; i++){
			if (a[i][y] == 1){
				tag = 1;
				break;
			}
			else if (a[i][y] == 3){
				num++;
				ans = ans < num ? ans : num;
				//printf("sx=%d sy=%d x=%d y=%d ans=%d  num=%d\n", sx, sy, x, y, ans, num);
				return;
			}
			else if (a[i][y] == 0)flag = 1;
		}
		if (flag){
			if (tag){
				a[i][y] = 0;
				dfs(i - 1, y, num + 1);
				a[i][y] = 1;
			}
			
		}
		
	}
}
int main(){
	while (1){
		cin >> w >> h;
		if (w == 0)break;
		for (int i = 0; i < h; i++){
			for (int j = 0; j < w; j++){
				//scanf("%d", &a[i][j]);
				cin >> a[i][j];
				if (a[i][j] == 2){
					a[i][j] = 0;
					sx = i, sy = j;
				}
			}
		}
		ans = 100;
		dfs(sx, sy, 0);
		if (ans>10)printf("-1\n");
		else printf("%d\n", ans);
	}
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值