51Nod1572 宝岛地图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42391248/article/details/87024448

1572 宝岛地图

  1. 1 秒
  2. 131,072 KB
  3. 20 分
  4. 3 级题

勇敢的水手们到达了一个小岛,在这个小岛上,曾经有海盗在这里埋下了一些宝藏。然而,我们的船快抛锚了,与此同时,船长发现藏宝图的一角被老鼠咬掉了一块。

藏宝图可以用一个n×m大小的矩形表示。矩形中的每一小块表示小岛中的一小块陆地(方块的边长为1米)。有一些方块表示的是海,这些块人是不能通过的。除了海不能走,其它的小方块都是可以行走的。在可行走区域里有一些小方块表示一些已知的地点。

另外,在地图上有k条指令。每条指令的格式表示如下:

“向y方向走n米”。

这里的方向有四种:“北”,“南”,“东”,“西”。如果你正确的跟着这些指令行走,并且完整的执行完所有指令,你就可以找到宝藏所在的地点。

但是,很不幸,由于地图中好多地方都缺失了,船长也不知道从哪些地方开始走。但是船长依然清楚地记得一些已知的地点。另外,船长也知道所有可行走区域。

现在船长想知道从哪些已知地点出发,按照指令,可能找到宝藏所在地。


收起

输入

单组测试数据
第一行包含两整数n和m(3≤n,m≤1000)。
接下来的n行每行有m个字符,表示整个地图。
“#”代表海。在地图矩形中,矩形的四周一圈一定是海。
“.”代表可行走区域,未知地点。大写字母“A”到“Z”表示可行走区域,已知地点。
所有大写字母不一定都被用到。每个字母在地图中最多出现一次。所有已知地点用不同的大写字母表示。

接下来一行有一个整数k(1≤k≤10^5),接下来有k行。
每行表示一条指令。
指令格式为“dir len”,“dir”表示朝哪个方向走,“len”表示走几步。
“dir”有四种取值“N”,“S”,“E”,“W”,对应题目中的“北”,“南”,“东”,“西”
在地图中,北是在顶部,南是在底部,西是在左边,东是在右边。“len”是一个整数,范围在[1,1000]。

输出

共一行,按字典序升序打印出所有可以完整执行地图中指令的已知区域的字母,如果没有满足要求的已知区域,则打印“no solution”(没有引号)。

输入样例

输入样例1
6 10
##########
#K#..#####
#.#..##.##
#..L.#...#
###D###A.#
##########
4
N 2
S 1
E 1
W 2

输出样例

输出样例1
AD

解题思路

暴力模拟肯定不行,可以预处理每个点到海的距离,然后判断。难点在于预处理的操作上。预处理的思想:从一个点向左走一下,表示从现在的位置到原来的点的距离为1.

AC代码

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
char map[1000][1000];
int Map[1000][1000][4];
struct action{
	int dir;
	int step;
}a[100000];
int k;
int Action(int x,int y)
{
	for(int i=0;i<k;i++)
	{
		if((int)fabs(a[i].step)>Map[x][y][a[i].dir]) return 0;
		else
			if(a[i].dir==1||a[i].dir==0)		
				x+=a[i].step;
			else
				y+=a[i].step;				
	}
	return 1;
}
char ans[1000000];
int main() 
{ 
	int n,m,i,j;
	cin>>n>>m;
	for(i=0;i<n;i++)
		for(j=0;j<m;j++)
			cin>>map[i][j];
	cin>>k;
	for(i=0;i<k;i++)
	{
		char ch;
		cin>>ch>>a[i].step;
		if(ch=='N')
		{
			a[i].dir=0;
			a[i].step=0-a[i].step;
		}	
		else if(ch=='S')
			a[i].dir=1;
		else if(ch=='W')
		{
			a[i].dir=2;
			a[i].step=0-a[i].step;
		}
		else
			a[i].dir=3;
	}
	int temp=0;
	//预处理 
	for(i=0;i<n;i++)//东 
	{
		int num=0;
		for(j=0;j<m;j++)
			if(map[i][j]!='#')
				Map[i][j][2]=num++;
			else num=0; 
		num=0;//西 
		for(j=m-1;j>=0;j--)
			if(map[i][j]!='#')
				Map[i][j][3]=num++;
			else num=0; 
	}	
	for(j=0;j<m;j++)//北 
	{
		int num=0;
		for(i=0;i<n;i++)
			if(map[i][j]!='#')
				Map[i][j][0]=num++;
			else num=0; 
		num=0;//南 
		for(i=n-1;i>=0;i--)
			if(map[i][j]!='#')
				Map[i][j][1]=num++;
			else num=0; 
	}	
	for(i=0;i<n;i++)
		for(j=0;j<m;j++)
			if(isalpha(map[i][j]))
				if(Action(i,j)) ans[temp++]=map[i][j];
	if(temp==0) cout<<"no solution"<<endl;
	else
	{
		sort(ans,ans+temp);
		cout<<ans;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42391248/article/details/87024448