Flood Fill
1.Lake Counting
题目http://ybt.ssoier.cn:8088/problem_show.php?pid=1249
自己写的(好理解)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=120;
int n,m;
char a[N][N];
bool st[N][N];
int sum;
int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
void bfs(int x,int y)
{
st[x][y]=true;
for(int i=0;i<4;i++)
{
int xx=dx[i]+x,yy=dy[i]+y;
if(a[xx][yy]=='W'&&!st[xx][yy])
bfs(xx,yy);
}
}
void solve()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='W'&&!st[i][j])
{
sum++;
bfs(i,j);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
solve();
cout<<sum;
}
y总的 (标准)(手写队列)
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> pii;
const int N=115;
int n,m,cnt=0;
char g[N][N];
bool st[N][N];
pii q[N*N];
void bfs(int sx,int sy)
{
int hh=0,tt=0;
q[0]={sx,sy};
st[sx][sy]=true;
while(hh<=tt)
{
auto t=q[hh++];
for(int i=t.x-1;i<=t.x+1;i++)//因为求八个周围的,则循环枚举两层即可
for(int j=t.y-1;j<=t.y+1;j++)
{
if(i<0||i>=n||j<0||j>=m) continue;//假如越界则continue
if(st[i][j]) continue;//假如标记过则continue
if(g[i][j]=='.') continue;//假如是干燥的则continue
st[i][j]=true;//标记这个点被标记过
q[++tt]={i,j};//把这个积水放进队列用,以后用他来更新其他的积水
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>g[i];
for(int i=0;i<n;i++)//遍历每一个点
for(int j=0;j<m;j++)
if(!st[i][j]&&g[i][j]=='W')//假如之前没标记过并且是新的水洼
{
bfs(i,j);//遍历这个水洼覆盖的水洼
cnt++;//水洼数量加一
}
cout<<cnt<<endl;
return 0;
}
2.The Castle(城堡问题)
题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1250
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
const int N=55;
int g[N][N];
bool st[N][N];
PII q[N*N];
int n,m;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
int bfs(int x,int y)
{
int hh=0,tt=0;
int area=0;
q[0]={x,y};
st[x][y]=true;
while(hh<=tt)
{
PII t=q[hh++];
area++;
for(int i=0;i<4;i++)
{
int a=t.x+dx[i],b=t.y+dy[i];
if(a<0||a>=n||b<0||b>=m)continue;
if(st[a][b])continue;
if((g[t.x][t.y]>>i) & 1)continue;//判断该方向上 边有没有墙
q[++tt]= {a,b};
st[a][b]=true;
}
}
return area;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>g[i][j];
int cnt=0,area=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(!st[i][j])
{
area=max(area,bfs(i,j));
cnt++;
}
}
cout<<cnt<<endl<<area;
}
3.山峰和山谷
题目http://ybt.ssoier.cn:8088/problem_show.php?pid=1454
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
const int N=1010;
int h[N][N];
bool st[N][N];
PII q[N*N];
int n;
int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
void bfs(int x,int y,bool &has_higher,bool &has_lower)
{
int hh=0,tt=0;
q[hh]={x,y};
st[x][y]=true;
while(hh<=tt)
{
PII t=q[hh++];
for(int i=0;i<8;i++)
{
int xx=t.x+dx[i],yy=t.y+dy[i];
if(xx<=0||xx>n||yy<=0||yy>n)continue;
if(h[xx][yy]>h[t.x][t.y])
has_higher=true;
else if(h[xx][yy]<h[t.x][t.y])
has_lower=true;
else if(!st[xx][yy])
{
st[xx][yy]=true;
q[++tt]={xx,yy};
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>h[i][j];
int peak=0,valley=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(!st[i][j])
{
bool has_higher=false,has_lower=false;
bfs(i,j,has_higher,has_lower);
if(!has_higher)peak++;
if(!has_lower)valley++;
}
}
cout<<peak<<" "<<valley;
}
最短路模型
1.迷宫问题
题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1255
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
const int N=10;
int n;
int g[N][N];
PII q[N*N];
PII pre[N][N];
bool st[N][N];
int dx[]={-1,0,1,0},dy[]={0,-1,0,1};
void bfs(int x,int y)
{
int hh=0,tt=0;
q[0]={x,y};
st[x][y]=true;
pre[x][y]={0,0};
while(hh<=tt)
{
PII t=q[hh++];
for(int i=0;i<4;i++)
{
int xx=t.x+dx[i],yy=t.y+dy[i];
if(xx<0||xx>=n||yy<0||yy>=n)continue;
if(st[xx][yy])continue;
if(g[xx][yy])continue;
pre[xx][yy]=t;
q[++tt]={xx,yy};
st[xx][yy]=true;
}
}
}
int main()
{
n=5;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>g[i][j];
bfs(n-1,n-1);
PII end(0,0);
while(true)
{
cout<<"("<<end.x<<", "<<end.y<<")"<<endl;
if(end.x==n-1&&end.y==n-1)break;
end=pre[end.x][end.y];
}
}
2.武士风度的牛
题目 https://www.acwing.com/problem/content/190/
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
const int N=160;
int n,m;
char g[N][N];
PII q[N*N];
bool st[N][N];
int dx[]={-1,-2,-2,-1,1,2,2,1},dy[]={-2,-1,1,2,2,1,-1,-2};
int dist[N][N];
void bfs(int x,int y)
{
int hh=0,tt=0;
q[0]={x,y};
st[x][y]=true;
dist[x][y]=0;
while(hh<=tt)
{
PII t=q[hh++];
for(int i=0;i<8;i++)
{
int xx=t.x+dx[i],yy=t.y+dy[i];
if(xx<0||xx>=m||yy<0||yy>=n)continue;
if(st[xx][yy])continue;
if(g[xx][yy]=='*')continue;
dist[xx][yy]=dist[t.x][t.y]+1;
q[++tt]={xx,yy};
st[xx][yy]=true;
}
}
}
int main()
{
cin>>n>>m;
int sx,sy,ex,ey;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>g[i][j];
if(g[i][j]=='K')sx=i,sy=j;
if(g[i][j]=='H')ex=i,ey=j;
}
bfs(sx,sy);
cout<<dist[ex][ey];
}
3.抓住那头牛
题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1253
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,k;
int dist[N];//记录每个点到起点的步数
int q[N];
int bfs()
{
int hh=0,tt=0;
q[0]=n;
memset(dist,-1,sizeof dist);
dist[n]=0;
while(hh<=tt)
{
int t=q[hh++];
if(t==k) return dist[k];//返回到起点的步数
if(t+1<N&&dist[t+1]==-1)//第一种情况走,且该位置没有被走过
{
dist[t+1]=dist[t]+1;//则该点距离+1
q[++tt]=t+1;//将该点放进队列中
}
if(t-1>=0&&dist[t-1]==-1)//第二种情况走,且该位置没有被走过
{
dist[t-1]=dist[t]+1;//则该点距离+1
q[++tt]=t-1;//将该点放进队列中
}
if(2*t<N&&dist[2*t]==-1)//第三种情况走,且该位置没有被走过
{
dist[2*t]=dist[t]+1;//则该点距离+1
q[++tt]=2*t;//将该点放进队列中
}
}
return 0;
}
int main()
{
cin>>n>>k;
cout<<bfs()<<endl;//输出最小步数
return 0;
}