题面
Problem Description
给定一个n行m列的网格地图,从上到下依次编号为第1行到第n行,从左往右依次编号为第1列到第m列。每个格子要么可以通行(用"."表示),要么不可通行(用"#"表示)。
玩家P现在位于某个可以通行的格子上,小地图显示出了玩家所在位置周围3×3=9个格子。请写一个程序,根据地图和小地图找到玩家可能所在的位置。
Input
第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。
每组测试数据第一行包含两个正整数n,m(1≤n,m≤100),表示行数和列数。
接下来n行,每行包含一个长度为m的字符串,依次描述每一行每个格子的情况。字符串仅由"."和"#"构成。
接下来3行,每行包含一个长度为3的字符串,描述玩家所在位置周围的情况。字符串由"."、"#"、"P"(表示玩家所在位置)和"*"(表示超出地图的部分)构成。
输入数据保证有且仅有一个"P",且"P"一定位于小地图的第2行第2列。
请注意:你不能旋转/翻转小地图。
Output
对于每组数据,输出一行一个整数,即玩家可能所在的位置的数量。
Sample Input
2
5 8
.#....#
.#..#..
.#..#.#.
..###..
...#....
.#.
P.
...
1 2
.#
*P#
Sample Output
2
1
思路
上来看就是搜索,然后看了一下,其实也并不是搜索,严格来说就是偏移一下原坐标,然后判断一下是不是和现在的周围坐标相等,如果不等直接退出,记得剪枝。
代码实现
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
char maze[105][105];
int n,m,cnt;
char now[4][4];
char be[4][4];
int moving[8][2]={{1,-1},{1,0},{1,1},{-1,-1},{0,1},{0,-1},{-1,0},{-1,1}};
bool check (int x,int y) {
if (x>=1&&y>=1&&x<=n&&y<=m) return true;
return false;
}
void bfs (int x,int y) {
for (int i=0;i<8;i++) {
int nx=x+moving[i][0];
int ny=y+moving[i][1];
if (check(nx,ny)) {
now[2+moving[i][0]][2+moving[i][1]]=maze[nx][ny];
if (now[2+moving[i][0]][2+moving[i][1]]!=be[2+moving[i][0]][2+moving[i][1]]) return;
}
else {
now[2+moving[i][0]][2+moving[i][1]]='*';
if (now[2+moving[i][0]][2+moving[i][1]]!=be[2+moving[i][0]][2+moving[i][1]]) return ;
}
}
cnt++;
}
int main () {
int t;
cin>>t;
while (t--) {
cin>>n>>m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) cin>>maze[i][j];
cnt=0;
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++) cin>>be[i][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) {
if (maze[i][j]!='#')
bfs(i,j);
}
cout<<cnt<<endl;
}
return 0;
}