• 洛谷


    https://www.luogu.org/problemnew/show/P1141

    能互相到达的格子的答案自然是一样的,第一次dfs标记联通块,第二次dfs把cnt传递到整个联通卡并顺手消除vis标记(其实把vis标记改成另一个也可以的)。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    int n,m;
    int g[1005][1005];
    int ans[1005][1005];
    
    int cnt=0;
    int vis[1005][1005];
    
    void dfs(int r,int c){
        //printf("%d %d
    ",r,c);
        vis[r][c]=1;
        cnt++;
        if(r-1>=1&&vis[r-1][c]==0&&g[r][c]!=g[r-1][c])
            dfs(r-1,c);
        if(r+1<=n&&vis[r+1][c]==0&&g[r][c]!=g[r+1][c])
            dfs(r+1,c);
        if(c-1>=1&&vis[r][c-1]==0&&g[r][c]!=g[r][c-1])
            dfs(r,c-1);
        if(c+1<=n&&vis[r][c+1]==0&&g[r][c]!=g[r][c+1])
            dfs(r,c+1);
    }
    
    void dfs2(int r,int c){
        vis[r][c]=0;
        ans[r][c]=cnt;
        if(r-1>=1&&vis[r-1][c])
            dfs2(r-1,c);
        if(r+1<=n&&vis[r+1][c])
            dfs2(r+1,c);
        if(c-1>=1&&vis[r][c-1])
            dfs2(r,c-1);
        if(c+1<=n&&vis[r][c+1])
            dfs2(r,c+1);
    }
    
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%1d",&g[i][j]);
                //printf("%d!
    ",g[i][j]);
            }
        }
    
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(ans[i][j]==0){
                    cnt=0;
                    //memset(vis,0,sizeof(vis));
                    dfs(i,j);
                    dfs2(i,j);
                }
            }
        }
    
        for(int i=1;i<=m;i++){
            int r,c;
            scanf("%d%d",&r,&c);
            printf("%d
    ",ans[r][c]);
        }
    }
  • 相关阅读:
    单向链表的创建、输出、插入、删除
    linux文件管理指令
    二叉树的创建与遍历(递归)
    小工具
    排序
    Project Euler Problem (1~10)
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta冲刺 7
    Beta冲刺 6
  • 原文地址:https://www.cnblogs.com/Yinku/p/10658621.html
Copyright © 2020-2023  润新知