【搜索】难缠的值周生

难缠的值周生
【问题描述】
小 P 上学总是迟到,迟到了以后常常会被值周生发现。被值周生发现就会给
他所在的班级扣分,被扣了分不免要挨班主任的训,这令小 P 很不爽。不过,聪
明的他经过观察发现,值周生通常会站在固定的位置,并且他们都很笨,只会向
固定的同一个方向看。于是小 P 经过潜心研究,把值周生的站位和方向以及学校
的地形绘成一张地图,你的任务是编写一个程序,帮助小 P 找出一条路从大门到
达教室并且不被值周生发现。
 
【输入文件】
输入文件的第一行是两个整数 N,G,代表学校是一个N × N的正方形,其
中有 G 个值周生。
接下来输入一个 N  ×  N 的矩阵,代表学校。其中.代表空地,X(大写英文字
母)代表墙,E 代表学校的大门,小 P 将从这里进入学校,C 代表教室,小 P 到
达这里就胜利了。数字代表值周生,数字的值代表值周生的编号,显然值周生不
能穿墙透视,但是小 P 也不能翻墙或者站到墙上去。
接下来有 G 行,每行包含一个数字Gi 和一个字母,代表第 Gi 个值周生的朝
向。其中 N 表示北,S 表示南,E 表示东,W 表示西。显然,如果你撞上值周
生(走到值周生所在的格子上),也会被值周生发现。
 
【输出文件】
输出文件包含任意一个行走方案,每行一个字母,表示小P 每步走的方向。
如果无论小P 怎么走都不能不被值周生发现的走到教室,则输出一行整数-1。
 
【样例输入】
5 3
..E.1
...XX
.2.X.
.C.X.
...X3
1 E
2 E
3 W

 


对,没有错,这是冬令营的题。。

有的同学因为想多了,或者想少了而悲剧。

我一开始差点忘了无答案输出-1。。

事实证明测试数据全是-1。


#include <cstdio>
long N;long G;
long gx[15];
long gy[15];
long dx[4] = {-1,0,1,0};
long dy[4] = {0,-1,0,1};

long Sx;long Sy;
long Ex;long Ey;

struct node
{
	long x;
	long y;	
	long f;
};
node que[500000];
bool map[15][15];
char ans[200];
long cnt=0;

void output(long r)
{
	cnt = 0;
	while (que[r].f)
	{
		long l = que[r].f;
		if (que[r].x==que[l].x)
		{
			if (que[r].y>que[l].y)
				ans[++cnt] = 'E';
			else
				ans[++cnt] = 'W';
		}
		else
		{
			if (que[r].x<que[l].x)
				ans[++cnt] = 'N';
			else
				ans[++cnt] = 'S';
		}
		r = l;
	}
	for (long i=cnt;i>0;i--)
	{
		printf("%c\n",ans[i]);
	}
}

void bfs()
{
	node uu;
	node vv;
	uu.x = Sx;
	uu.y = Sy;
	uu.f = 0;
	long l = 0;
	long r = 0;
	que[++r] = uu;
	
	while (l < r)
	{
		uu = que[++l];
		if (uu.x == Ex && uu.y == Ey)
		{
			output(l);
			return;
		}
		for (long i=0;i<4;i++)
		{
			vv.x = uu.x+dx[i];
			vv.y = uu.y+dy[i];
			if (map[vv.x][vv.y])
			{
				vv.f = l;
	  			map[vv.x][vv.y] = false;
				que[++r] = vv;
			}
		}
	}
	printf("-1");
}

int main()
{
	freopen("guard.in","r",stdin);
	freopen("guard.out","w",stdout);
	
	scanf("%ld%ld",&N,&G);
 	for (long i=1;i<N+1;i++)
	{
		scanf("\n");
 		for (long j=1;j<N+1;j++)
		{
			char tmp;
			scanf("%c",&tmp);
			if (tmp == 'E')
			{
				Sx = i;
				Sy = j;
				map[i][j] = true;
			}
			else if (tmp == 'X')
			{
				map[i][j] = false;
			}
			else if (tmp == '.')
			{
				map[i][j] = true;
			}
			else if (tmp == 'C')
			{
				map[i][j] = true;
				Ex = i;
				Ey = j;
			}
			else
			{
				long index = tmp-'0';
				gx[index] = i;
				gy[index] = j;
				map[i][j] = true;
			}
		}
	}
	for (long i=0;i<N+2;i++)
	{
		map[0][i] = map[i][0] = map[N+1][i] = map[i][N+1] = false;
	}
	for (long k=1;k<G+1;k++)
	{
		long ind;char dir;
		scanf("%ld",&ind);
		scanf(" ");
		scanf("%c",&dir);
		if (dir == 'N')
		{
			long j = gy[ind];
			for (long i=gx[ind];i>0&&map[i][j];i--)
			{
				map[i][j] = false;
			}
		}
		if (dir == 'S')
		{
			long j = gy[ind];
			for (long i=gx[ind];i<N+1&&map[i][j];i++)
			{
				map[i][j] = false;	
			}	
		}
		if (dir == 'W')
		{
			long i = gx[ind];
			for (long j=gy[ind];j>0&&map[i][j];j--)
			{
				map[i][j] = false;
			}
		}
		if (dir == 'E')
		{
			long i = gx[ind];
			for (long j=gy[ind];j<N+1&&map[i][j];j++)
			{
				map[i][j] = false;	
			}
		}
	}
	if (!map[Sx][Sy])
	{
		printf("-1");
		return 0;
	}
	bfs();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值