PKU 3009 -- Curling 2.0 - xIao_wU 思维磁场 - Just Run And Never Forget I Have A Dream

PKU 3009 -- Curling 2.0

xIao.wU posted @ 2010年1月28日 00:04 in 搜索 , 986 阅读

    刚开始毋庸置疑的敲了个BFS,想到可以轻轻松松过掉,发现样例过不了,怪怪的。细想一下,发现BFS中保存的vis数组中,若之前给碰掉的墙块就成为空的,将导致其他状态中也无视了这个块,若每个状态都要保存一个20 * 20的矩阵的话,空间消耗是可想而知的。故可以利用dfs的回溯,由于不用考虑最优值,只要找出步数小于10的即可,DFS恰好可以解决此题的空间问题。

    觉得这题挺不错的,之前做的,一直没有写出解题报告,前段日子太忙了 - -#

CODE:

 

#include <iostream>
using namespace std;

const int N = 25;
struct node {
	int x , y , step;
} Que[N * N * N] ,S , T ,ans[N];
int sqr[N][N], w , h , head , tail;
int dir[4][2] = { {1 , 0} , {-1 , 0} , {0 , -1} , {0 , 1} };
int ret ;

void DFS(int a , int b , int step) {
	if(step > 10 || step > ret) return;
	for(int i=0; i < 4; i++) {
		int at = a + dir[i][0];
		int bt = b + dir[i][1];
		if(at <= 0 || bt <= 0 || at > h || bt > w)
			continue;
		if(sqr[at][bt] == 1) continue;
		int flag = 0;
		int tx = a, ty = b;
		while(sqr[at][bt] != 1) {
			tx = at , ty = bt;
			if(sqr[at][bt] == 3 && step + 1 <= 10) {
				ret = min(ret , step + 1);
			}
			at += dir[i][0];
			bt += + dir[i][1];
			if(at <= 0 || bt <= 0 || at > h || bt > w) {
				flag = 1; 
				break;
			}
		}
		if(flag) continue;
		sqr[at][bt] = 0;
		DFS(tx , ty , step + 1);
		sqr[at][bt] = 1;
	}
}

int main() {
	//freopen("in.txt" , "r" , stdin);
	while(scanf("%d %d" , &w , &h), w && h) {
		int sx ,sy;
		ret = 20;
		for(int i=1; i <= h; i++)
			for(int j=1; j <= w; j++) {
				scanf("%d" , &sqr[i][j]);
				if(sqr[i][j] == 2) {
					sx = i;
					sy = j;
				}
			}
		DFS(sx , sy , 0);
		printf("%d\n" , ret == 20 ? -1 : ret);
	}
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee