勇敢的水手们到达了一个小岛,在这个小岛上,曾经有海盗在这里埋下了一些宝藏。然而,我们的船快抛锚了,与此同时,船长发现藏宝图的一角被老鼠咬掉了一块。
藏宝图可以用一个n×m大小的矩形表示。矩形中的每一小块表示小岛中的一小块陆地(方块的边长为1米)。有一些方块表示的是海,这些块人是不能通过的。除了海不能走,其它的小方块都是可以行走的。在可行走区域里有一些小方块表示一些已知的地点。
另外,在地图上有k条指令。每条指令的格式表示如下:
“向y方向走n米”。
这里的方向有四种:“北”,“南”,“东”,“西”。如果你正确的跟着这些指令行走,并且完整的执行完所有指令,你就可以找到宝藏所在的地点。
但是,很不幸,由于地图中好多地方都缺失了,船长也不知道从哪些地方开始走。但是船长依然清楚地记得一些已知的地点。另外,船长也知道所有可行走区域。
现在船长想知道从哪些已知地点出发,按照指令,可能找到宝藏所在地。
Input第一行包含两整数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。
输入样例1 6 10 ########## #K#..##### #.#..##.## #..L.#...# ###D###A.# ########## 4 N 2 S 1 E 1 W 2
输出样例1 AD
————————————————————————————————————————————
本题先是用暴力把每个指令都模拟一遍,有几个测试点超时,然后发现没必要一步一步的走,如果能判断直接行走len步的过程中是否遇见#就方便多了,所以先输入地图的时候预处理出每一行中有#的是哪几列,每一列中有#的是哪几行,然后按照每一步的指令方向走,如果#在行走的区间内就标记终止循环。#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int M = 1005;
vector<int>column[M];
vector<int>row[M];
char map[M][M];
struct Node
{
int x;
int y;
bool exist=false;
}ch[26];
struct Operate
{
int len;
char dir;
}op[100005];
bool ans[26];
int main()
{
int n,m;
memset(ans, false, sizeof(ans));
char c;
bool flag;
scanf("%d%d", &n, &m);
getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
map[i][j] = getchar();
c=map[i][j];
if(c>='A'&&c<='Z')
{
ch[c-'A'].exist = true;
ch[c-'A'].x = i;
ch[c-'A'].y = j;
}
else if(c=='#')
{
column[j].push_back(i);
row[i].push_back(j);
}
}
getchar();
}
int k;
scanf("%d", &k);
getchar();
for(int i=1;i<=k;i++)
{
scanf("%c %d", &op[i].dir, &op[i].len);
getchar();
}
int xt,yt,xtt,ytt;
for(int i=0;i<26;i++)
{
if(ch[i].exist)
{
// printf("-----------%c\n", 'A' +i);
flag = true;
xt = ch[i].x;
yt = ch[i].y;
for(int j=1;j<=k;j++)
{
if(op[j].dir=='N')
{
xtt = xt - op[j].len;
if(xtt<=1)
{
flag = false;
break;
}
vector<int>::iterator it=column[yt].begin();//vector迭代器,it相当于指针
for(;it!=column[yt].end();it++)
{
if(xt-*it>0&&xt-xtt>=xt-*it)
{
flag = false;
break;
}
}
if(flag)
xt = xtt;
}
else if(op[j].dir=='S')
{
xtt = xt + op[j].len;
if(xtt>=n)
{
flag = false;
break;
}
vector<int>::iterator it=column[yt].begin();
for(;it!=column[yt].end();it++)
{
if(*it-xt>0&&*it-xt<=xtt-xt)
{
flag = false;
break;
}
}
if(flag)
xt = xtt;
}
else if(op[j].dir=='W')
{
ytt = yt - op[j].len;
if(ytt<=1)
{
flag = false;
break;
}
vector<int>::iterator it=row[xt].begin();
for(;it!=row[xt].end();it++)
{
// printf("W=%d\n", *it);
if(yt-*it>0&&yt-ytt>=yt-*it)
{
flag = false;
break;
}
}
if(flag)
yt = ytt;
}
else if(op[j].dir=='E')
{
ytt = yt + op[j].len;
if(ytt>=m)
{
flag = false;
break;
}
vector<int>::iterator it=row[xt].begin();
for(;it!=row[xt].end();it++)
{
if(*it-yt>0&&ytt-yt>=*it-yt)
{
flag = false;
break;
}
}
if(flag)
yt = ytt;
}
if(!flag)
break;
// printf("xt=%d yt=%d\n", xt, yt);
}
if(flag)
ans[i] = true;
else
continue;
}
}
int cnt=0;
for(int i=0;i<26;i++)
{
if(ans[i])
printf("%c", 'A'+i);
else
cnt++;
}
if(cnt==26)
printf("no solution");
return 0;
}