非常简单经典的DFS
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
char a[21][21];
int ans = 0;
bool vis[21][21];
int w,h;
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
void dfs(int x,int y)
{
ans++;
vis[x][y] = true;
for(int i = 0; i < 4; i++){
int xx = x+dx[i];
int yy = y+dy[i];
if(xx<0||xx>h||yy<0||yy>w) continue;
if(vis[xx][yy]) continue;
if(a[xx][yy]!='.') continue;
dfs(xx,yy);
}
}
int main()
{
int x=0,y=0;
cin >>w>>h;
for(int i = 0; i < h; i++){
for(int j = 0; j < w; j++){
cin >>a[i][j];
if(a[i][j]=='@') x=i,y=j;
}
}
dfs(x,y);
cout << ans;
return 0;
}
求最短距离-BFS 也是常规套路简单题
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int m,n;
char g[21][21];
bool vis[21][21];
int ans = 0;
struct node
{
int x,y;
int step;//不用记录该点的符号,用g[v.x][v.y]即可求得
node(){}
node(int x,int y,int step):x(x),y(y),step(step){}
};
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
int bfs(int x,int y,int s,int t)
{
queue<node> q;
q.push(node(x,y,0));
node e,v;
while(!q.empty()){
e = q.front();
q.pop();
for(int i = 0; i < 4; i++){
v.x = e.x+dx[i];
v.y = e.y+dy[i];
v.step = e.step + 1;
//搜索到终点
if(v.x==s&&v.y==t){
return v.step;
}
//判断出界
if(v.x<0||v.x>=m||v.y<0||v.y>=n) continue;//边界判断错误写成v.x<m,v.y>n导致少过3组样例
if(vis[v.x][v.y]) continue;
//标记该点并继续搜索
vis[v.x][v.y] = true;
q.push(v);
}
}
return -1;
}
int main()
{
int x=0,y=0,s=0,t=0;
cin >>m>>n;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cin >>g[i][j];
if(g[i][j]=='@') x=i,y=j;
if(g[i][j]=='*') s=i,t=j;
if(g[i][j]=='#') vis[i][j] = true;
}
}
cout << bfs(x,y,s,t);
return 0;
}
用优先队列即可;注意重载<的两种方式
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m;
char g[201][201];
bool vis[201][201];
int rx,ry,ax,ay;
struct node
{
int x,y;
int step;//不用记录该点的符号,用g[v.x][v.y]即可求得
node(){}
node(int x,int y,int step):x(x),y(y),step(step){}
bool operator < (const node& e)const
{
return step > e.step;
}
// friend bool operator < (const node& a, const node& b)
// {
// return a.step > b.step;
// }
};
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
int bfs()
{
priority_queue<node> q;
q.push(node(rx,ry,0));
vis[rx][ry] = true;
node e,v;
while(!q.empty()){
e = q.top();
q.pop();
for(int i = 0; i < 4; i++){
v.x = e.x+dx[i];
v.y = e.y+dy[i];
v.step = e.step + 1;
//搜索到终点
if(v.x==ax&&v.y==ay){
return v.step;
}
//判断出界
if(v.x<0||v.x>=n||v.y<0||v.y>=m) continue;
if(vis[v.x][v.y]) continue;
//标记该点并继续搜索
if(g[v.x][v.y]=='x') v.step++;
vis[v.x][v.y] = true;
q.push(v);
}
}
return -1;
}
int main()
{
cin >>n>>m;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> g[i][j];
if(g[i][j]=='r') rx=i,ry=j;
if(g[i][j]=='a') ax=i,ay=j;
if(g[i][j]=='#') vis[i][j] = true;
}
}
int ans = bfs();
if(ans==-1) cout << "Impossible";
else cout << ans;
return 0;
}
4.蓝桥杯剪格子
关键在于回溯
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int m,n;
int a[11][11];
int ans = 0,tot = 0;
bool vis[11][11];
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
void dfs(int x,int y,int cnt,int sum)
{
// printf("(%d,%d) cnt=%d sum=%d\n",x,y,cnt,sum);
if(sum*2==tot){
ans = cnt;
return;
}
if(sum*2>tot) return;
for(int i = 0; i < 4; i++){
int xx = x + dx[i];
int yy = y + dy[i];
if(xx<0||xx>=n||yy<0||yy>=m) continue;
if(vis[xx][yy]) continue;
vis[xx][yy] = true;
dfs(xx,yy,cnt+1,sum+a[xx][yy]);
vis[xx][yy] = false;//关键:回溯
}
}
int main()
{
cin >>m>>n;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >>a[i][j];
tot += a[i][j];
}
}
// printf("tot=%d\n",tot);
dfs(0,0,1,a[0][0]);
cout << ans;
return 0;
}