poj1024

参考:http://hi.baidu.com/lewutian/item/2624b2ebd1c0e4255b2d64eb

参考:discuss

 (1)求各点到源点的最小步数(DFS)
(2)求各点到终点的最小步数(DFS)
(3)如果点不是给定路径上的点,那么:该点到源点的最小步数+该点到终点的最小步数<=给定路径的步数,否则给定路径不是唯一最短的

 (4)如果两相邻点a、b之间存在墙,那么:a到源点的最小步数+1+b到终点的最小步数<=给定路径的步数
                          或者 a到终点的最小步数+1+b到源点的最小步数<=给定路径的步数,否则墙多余


/*Source Code

*Problem: 1024  
*Memory: 288K  Time: 16MS 
*Language: C++  Result: Accepted 
*/


#include<stdio.h>
#include<memory.h>


#define GRAPH_SIZE 100//一开始取20,老是WA,改成100才AC

struct point
{
	int len[2];//len[0]表示点到源点的距离,len[1]表示点到终点的距离
	bool used;//点是否在最短路径上
	bool r, u;//点的右边或上边是否有墙
}p[GRAPH_SIZE][GRAPH_SIZE];//p为包括GRAPH_SIZE*GRAPH_SIZE个点的迷宫

int dX, dY;//记录终点
int height, width;//迷宫的高度和宽度
int minPath;//给定的最短路径的长度

void DFS(int x, int y, int len, int flag);
bool judge();

int main()
{
	int testNum, wallNum;
	char path[GRAPH_SIZE*4];//路径
	int x,y,x1,y1,x2,y2;
	int i;
	
	scanf("%d", &testNum);
	while(testNum--)
	{
		memset(p,0,sizeof(p));
		scanf("%d %d", &width, &height);
		p[0][0].used = true;
		dX = 0;
		dY = 0;
		minPath = 0;
		scanf("%s",path);
		for (i=0; path[i]!='\0'; i++)
		{
			minPath++;

			if('U' == path[i])
				p[dX][++dY].used = true;
			if('D' == path[i])
				p[dX][--dY].used = true;
			if('L' == path[i])
				p[--dX][dY].used = true;
			if('R' == path[i])
				p[++dX][dY].used = true;
		}

		scanf("%d", &wallNum);
		while(wallNum--)
		{
			scanf("%d %d %d %d", &x1,&y1,&x2,&y2);
			x = x1 - x2;
			y = y1 - y2;

			if(x==0 && y==1)
				p[x2][y2].u = true;
			if(x==0 && y==-1)
				p[x1][y1].u = true;
			if(x==1 && y==0)
				p[x2][y2].r = true;
			if(x==-1 && y==0)
				p[x1][y1].r = true;
		}
		DFS(0,0,0,0);
		DFS(dX,dY,0,1);
		if(judge())
			printf("CORRECT\n");
		else
			printf("INCORRECT\n");
	}
	return 0;
}

void DFS(int x, int y, int len, int flag)
{
	if(len>=p[x][y].len[flag] && p[x][y].len[flag]!=0)
		return;
	if(x+y!=0 && (x!=dX || y!=dY))
		p[x][y].len[flag] = len;
	len++;
	if (p[x][y].r==false && x+1<width)
		DFS(x+1, y, len, flag);
	if (p[x][y].u==false && y+1<height)
		DFS(x, y+1, len, flag);
	if (x-1>=0 && p[x-1][y].r==false)
		DFS(x-1, y, len, flag);
	if (y-1>=0 && p[x][y-1].u==false)
		DFS(x, y-1, len, flag);
}

bool judge()
{
	int i, j;

	for (i=0; i<width; i++)
	{
		for (j=0; j<height; j++)
		{
			if (p[i][j].used==false && p[i][j].len[0]+p[i][j].len[1]<=minPath)
				return false;
			if (p[i][j].r==true && i+1<width && p[i][j].len[0]+p[i+1][j].len[1]+1>minPath && p[i][j].len[1]+p[i+1][j].len[0]+1>minPath)
				return false;
			if (p[i][j].u==true && j+1<height && p[i][j].len[0]+p[i][j+1].len[1]+1>minPath && p[i][j].len[1]+p[i][j+1].len[0]+1>minPath)
				return false; 
		}
	}
	return true;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值