Acwing2024蓝桥杯FloodFill

AcWing 687. 扫雷

模拟以下样例(10X10):

把扫雷地图转变为数字记录的地图:地雷记作-1,其余表示8个方向有几个地雷,完成后如下图:

接着搜索所有0联通块(为红色矩形),并且把联通块附近不是地雷的点(红色圆形)全标记为-1,如下图:

而答案就是当前该图中大于0的数的数目之和,再加上原来0联通块的数目,dfs(AC):

#include<iostream>
#include<cstring>
using namespace std;
const int N=305;
int T,n;
char a[N][N];   //原地图
int b[N][N];    //数字地图
bool flag[N][N];//标记数组
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
void dfs(int x,int y){
    if(b[x][y]>0) {b[x][y]=-1;return;}
    for(int i=0;i<8;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=n){
            if(!flag[xx][yy]){
                flag[xx][yy]=1;
                if(b[xx][yy]>=0){
                    dfs(xx,yy);
                }
            }
        }
    }
}
int main(){
    cin>>T;
    for(int i=1;i<=T;i++){
        cin>>n;
        cout<<"Case #"<<i<<":"<<" ";
        //地图转换
        for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++) 
                {cin>>a[i][j];if(a[i][j]=='*') b[i][j]=-1;}
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(a[i][j]=='.'){
                    int t=0;
                    for(int k=0;k<8;k++){
                        int x=i+dx[k],y=j+dy[k];
                        if(x>=1&&x<=n&&y>=1&&y<=n&&a[x][y]=='*'){
                            t++;
                        }
                    }
                    b[i][j]=t;
                }
            }
        }
        //各变量初始化
        int ans=0;
        memset(flag,0,sizeof flag);
        //搜索0联通块,并且计算联通块数目
        for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++) 
                if(!flag[i][j]&&b[i][j]==0) {flag[i][j]=1;dfs(i,j);ans++;}
        //计算剩余大于0数的数目,求得答案
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(b[i][j]>0) ans++;
        cout<<ans<<endl;
    }
    return 0;
}

AcWing 643. 动态网格

模拟+dfs:

#include<iostream>
#include<cstring>
using namespace std;
const int N=105;
int T,R,C,n;
char a[N][N];
bool flag[N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y){
    flag[x][y]=1;
    for(int i=0;i<4;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=0&&xx<R&&yy>=0&&yy<C){
            if(a[xx][yy]=='1'&&flag[xx][yy]==0){
                dfs(xx,yy);
            }
        }
    }
    return ;
}
int main(){
    cin>>T;
    for(int k=1;k<=T;k++){
        cin>>R>>C;
        for(int i=0;i<R;i++) for(int j=0;j<C;j++) cin>>a[i][j];
        cin>>n;
        cout<<"Case #"<<k<<":"<<endl;
        while(n--){
            int ans=0;
            memset(flag,0,sizeof flag);
            char ch;
            cin>>ch;
            if(ch=='M'){
                int x,y,z;
                cin>>x>>y>>z;
                if(z==1) a[x][y]='1';
                else a[x][y]='0';
            }
            else{
                for(int i=0;i<R;i++){
                    for(int j=0;j<C;j++){
                        if(a[i][j]=='1'&&flag[i][j]==0){
                            dfs(i,j);
                            ans++;
                        }
                    }
                }
                cout<<ans<<endl;
            }
        }
    }
    return 0;
}

AcWing 844. 走迷宫

bfs: 

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=110;
int n,m;
typedef pair<int,int>pii;
int mapp[N][N],d[N][N];
int bfs(){
    memset(d,-1,sizeof d);
    d[1][1]=0;
    queue<pii>q;
    q.push({1,1});
    int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    while(q.size()){
        auto t=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int x=t.first+dx[i],y=t.second+dy[i];
            if(x>=1&&x<=n&&y>=1&&y<=m&&d[x][y]==-1&&mapp[x][y]==0){
                d[x][y]=d[t.first][t.second]+1;
                q.push({x,y});
            }
        }
    }
    return d[n][m];
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mapp[i][j];
    cout<<bfs()<<endl;
    return 0;
}

AcWing 3224. 画图

这题最大的问题就是题目给的坐标不方便,只需要处理好坐标转换,再把两个操作函数写好即可:

#include<iostream>
#include<cstring>
using namespace std;
const int N=105;
int n,m,q;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
char a[N][N];
bool flag[N][N];
//画线函数
void line(int x1,int y1,int x2,int y2){
    if(x1==x2){//同一行
        for(int i=y1;i<=y2;i++){
            if(a[x1][i]=='|'||a[x1][i]=='+') a[x1][i]='+';
            else a[x1][i]='-';
        }
    }
    if(y1==y2){//同一列
        for(int i=x1;i<=x2;i++){
            if(a[i][y1]=='-'||a[i][y1]=='+') a[i][y1]='+';
            else a[i][y1]='|';
        }
    }
    return ;
}
//填充函数
void fills(int x,int y,char c){
    flag[x][y]=1;
    a[x][y]=c;
    for(int i=0;i<4;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=0&&xx<n&&yy>=0&&yy<m){
            if(a[xx][yy]!='-'&&a[xx][yy]!='|'&&a[xx][yy]!='+'){
                if(flag[xx][yy]==0){
                    fills(xx,yy,c);
                }
            }
        }
    }
    return ;
}
int main(){
    cin>>m>>n>>q;
    for(int i=0;i<n;i++) for(int j=0;j<m;j++) a[i][j]='.';
    while(q--){
        int t;
        cin>>t;
        if(t==0){
            int x1,y1,x2,y2;//x和y反着读入
            cin>>y1>>x1>>y2>>x2;
            if(x1>x2) swap(x1,x2);
            if(y1>y2) swap(y1,y2);
            line(x1,y1,x2,y2);
        }
        else{
            int x,y;char c;
            cin>>y>>x>>c;//x和y反着读入
            memset(flag,0,sizeof flag);
            fills(x,y,c);
        }
    }
    for(int i=n-1;i>=0;i--){
        for(int j=0;j<m;j++){
            cout<<a[i][j];
        }
        cout<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值