思路
首先将图中所有的点,都声明为题目的“不可到底”的点,这样在bfs或者dfs判断条件时候,判断走过的点,越界和不可走的点三者就可以合为一个条件,极大了减少了判断的复杂性
Acwing 1113.红与黑
//bfs
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef pair<int , int > PII;
int dx[] ={-1, 0, 1, 0}, dy[] ={0,1,0,-1};
const int N = 50;
char g[N][N];
void bfs(PII start){
int cnt = 1;
queue<PII> q;
q.push(start);
while(!q.empty()){
PII t = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int x = t.first + dx[i];
int y = t.second + dy[i];
if(g[x][y] == '#') continue;//此处判断越界、过墙和已经走过三种条件
else if(g[x][y] == '.'){
q.push({x,y});
cnt++;
g[x][y] = '#';//!!!!!尤其注意这里要将已经包含的点也给改为‘#’,否则会出现重复记录的情况
}
}
}
cout << cnt << endl;
return ;
}
int main(){
int w, h;
PII start;
while(cin >> w >> h, w || h){
memset(g,'#',sizeof g);//将g全部声明为红色瓷砖
for(int i = 1; i <= h; i++){//从1开始输入直接避免了边界问题
for(int j = 1; j <=w; j ++){
cin >> g[i][j];
if(g[i][j] == '@'){
start.first = i, start.second = j;
}
}
}
bfs(start);
}
return 0;
}
//dfs
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
typedef pair<int , int > PII;
int dx[] ={-1, 0, 1, 0}, dy[] ={0,1,0,-1};
const int N = 50;
char g[N][N];
int dfs(int a, int b){
int cnt = 1;
g[a][b] = '#';
for(int i = 0; i < 4; i++){
int x = a + dx[i];
int y = b + dy[i];
if(g[x][y] == '#') continue;//此处不仅判断红色瓷块还判断边界
else {
cnt += dfs(x,y);
}
}
return cnt;
}
int main(){
int w, h,x,y;
while(cin >> w >> h, w || h){
memset(g,'#',sizeof g);
for(int i = 1; i <= h; i++){//从1开始输入直接避免了边界问题
for(int j = 1; j <=w; j ++){
cin >> g[i][j];
if(g[i][j] == '@'){
x = i, y = j;
}
}
}
int cnt = dfs(x,y);
cout << cnt << endl;
}
return 0;
}
主要的用到的算法是 洪水灌溉算法,也就寻找最大连通快,flood fill算法
dfs代码简单,但是容易爆栈,在栈内存有1MB情况下容易爆,考试要记得注意栈内存
Acwing 献给阿尔吉侬的花束
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef pair<int , int> PII;
const int N = 250;
char g[N][N];//存地图
int dist[N][N];//存距离
int dx[]={-1,0,1,0},dy[] = {0,1,0,-1};
void bfs(PII start){
queue<PII>q;
q.push(start);
while(!q.empty()){
PII t = q.front();
q.pop();
for(int i = 0 ; i < 4; i++){
int x = t.first + dx[i];
int y = t.second + dy[i];
if(g[x][y] == '#') continue;
if(g[x][y] =='.'){
dist[x][y] = dist[t.first][t.second] + 1;
g[x][y] = '#';//表示已经走过的路就变成了墙,不可以再往回走
q.push({x,y});
}
else if(g[x][y] == 'E'){
cout << dist[t.first][t.second] + 1 << endl;
return ;
}
}
g[t.first][t.second] = '#';
}
cout <<"oop!" << endl;
return ;
}
int main(){
int t,r,c;cin >> t;
while(t--){
memset(g,'#',sizeof g);
memset(dist, 0,sizeof dist);
cin >> r >> c;
PII start;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)//从1开始减少了越界处理
{
cin >> g[i][j];
if(g[i][j] == 'S')
start.first = i,start.second = j;
}
bfs(start);
}
return 0;
}
此题思路与上一题类似