杭电oj1010

题目链接(temple of bone)
奇偶剪枝

#include
#include
char maze[26][26];//maze是迷宫的字符型数组
int si,sj,di,dj;//si是起始x坐标,sj是起始y坐标,di是结束x坐标,dj是结束y坐标
bool flag=false;//标记是否可以逃生
int direction[4][2]={1,0,-1,0,0,1,0,-1};//偏移数组,用于向右、左。下、上的顺序移动
int N=0,M,T;
void dfs(int px,int py,int time){
	if(flag)//如果已经成功过一次,直接返回,不用再验证后面的方法能否成功
		return;
	if(time>T)//如果时间已经超过了逃生时间。直接返回因为后面也不可成功
		return;
	if(maze[px][py]=='X')//如果下一步是X则不做操作,代表不能走这里
		return;
	if(px==di&&py==dj&&time==T){//如果在出口且时间正好是T则改变flag返回
		flag=true;
		return;
	}
	if(px<=0||py<=0||px>N||py>M)//若果下一步没有越界,且不是X(上面验证了)
		return;
	
		for(int i=0;i<4;i++){
		maze[px][py]='X';//把脚底下职位X,不能再返回
		dfs(px+direction[i][0],py+direction[i][1],time+1);//走向下一步,时间+1
		maze[px][py]='.';//递归回溯时,当前是可以走的(回到上一步)
		if(flag)//退出接口
		return;
	
	}
	
}
int main(){
	while(scanf("%d%d%d",&N,&M,&T)!=EOF){
		flag=false;					//必须设置flag为false否则影响下一次的判断
		getchar();					//吸收莫名其妙的空格
		
		if(N==0&&M==0&&T==0)			//退出条件
			break;
		for(int i=1;i<=N;i++){
			for(int j=1;j<=M;j++){
				scanf("%c",&maze[i][j]);	//给迷宫赋值
				if(maze[i][j]=='S'){
					si=i;sj=j;//找入口
					}
				if(maze[i][j]=='D'){//找出口
					di=i;dj=j;
				}	
			}
			getchar();//吸收多于字符
		}
		if((di+dj+si+sj+T)%2==1){//奇偶剪枝
			printf("NO\n");
			continue;
		}
		dfs(si,sj,0);
		if(flag)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

你可能感兴趣的:(杭电oj1010)