勇敢的水手们到达了一个小岛,在这个小岛上,曾经有海盗在这里埋下了一些宝藏。然而,我们的船快抛锚了,与此同时,船长发现藏宝图的一角被老鼠咬掉了一块。
藏宝图可以用一个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 1,1000。
输入样例1 6 10 ########## #K#..##### #.#..##.## #..L.#...# ###D###A.# ########## 4 N 2 S 1 E 1 W 2
输出样例1AD
思路 :做两个二维数组dp # 的个数,检测每次水平或者竖直移动 len 之间是否隔海。当然也可以设置一个三维数组,作用相同。在读入地图时存取出现的大写字母及其初始坐标,对每个指令依次判断,如果不行则标记,最后输出。
#include<iostream> #include<cstdio> #include<set> #include<map> #include<cstring> #include<algorithm> using namespace std; typedef pair <int ,int> ii; char mp[1100][1100]; int sea1[1100][1100]; // 列 int sea2[1100][1100]; // 行 map <char,ii > pos; map <char,ii > dir; map <char,int> mark; char record[26]; int main(){ int m,n; dir['N'].first = -1,dir['N'].second = 0; dir['S'].first = 1 ,dir['S'].second = 0; dir['E'].first = 0, dir['E'].second = 1; dir['W'].first = 0, dir['W'].second =-1; scanf("%d%d",&m,&n); getchar(); int k = 0; for(int i = 1; i <=m; i++) { for(int j = 1; j <=n; j++) { scanf("%c",&mp[i][j]); if(mp[i][j] >= 'A' && mp[i][j] <= 'Z') { char c = mp[i][j]; record[k++] = c; mark[c] = 1; pos[c].first = i; pos[c].second = j; } if(mp[i][j] == '#') { sea1[i][j] = sea1[i][j-1] + 1; sea2[i][j] = sea2[i-1][j] + 1; } else { sea1[i][j] = sea1[i][j-1] ; sea2[i][j] = sea2[i-1][j] ; } } getchar(); } int q,x; char s[10]; scanf("%d",&q); getchar(); while(q--) { scanf("%s%d",s,&x); for(int j = 0; j < k; j++) { char c = record[j]; if(!mark[c]) continue; int x_ = pos[c].first; int y_ = pos[c].second; int zx = x_ + dir[s[0]].first *x; int zy = y_ + dir[s[0]].second *x; pos[c].first = zx; pos[c].second = zy; if(zx < 1 || zy < 1 || zx > m || zy > n) { mark[c] = 0; continue; } if(s[0] == 'S') { if(sea2[zx][zy] - sea2[x_-1][y_]) { mark[c] = 0; continue; } } if(s[0] == 'E') { if(sea1[zx][zy] - sea1[x_][y_-1]) { mark[c] = 0; continue; } } if(s[0] == 'N') { if(sea2[x_][y_]-sea2[zx-1][zy]) { mark[c] = 0; continue; } } if(s[0] == 'W') { if(sea1[x_][y_]-sea1[zx][zy-1]) { mark[c] = 0; continue; } } } } bool yes = 1; for(int i = 0; i < 26; i++) { char c = 'A' + i; if(mark[c]) { yes = 0; printf("%c",c); } } if(yes) printf("no solution"); printf("\n"); return 0; }