当前位置: 首页 > 工具软件 > gym-fx > 使用案例 >

A - Artwork Gym - 101550A

谭越
2023-12-01

题意:给你n*m个格子每次添加一条黑线,问这些黑线将白格子分成几个部分。

题解:首先将全部黑线涂上,将每个格子标记在那个块上,对于询问从后往前删除,并将删除之后的白格子赋值为新的块,然后并查集合并,结果就是这次询问的块数。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int n,m,p;
struct node{
    int x1,y1,x2,y2;
}s[maxn*10]; int top=0;
int mp[maxn][maxn],vis[maxn][maxn],a[maxn][maxn],b[maxn*maxn];
int zhuan(int i,int j){
    return (i-1)*m+j;
}
void init(){

    for(int i=1;i<=n*m;i++) b[i]=i;
    for(int i=1;i<=p;i++){
        if(s[i].x1==s[i].x2){
            int y1=s[i].y1,y2=s[i].y2;
            for(int j=min(y1,y2);j<=max(y1,y2);j++){
                mp[s[i].x1][j]++;
            }
        }
        else if(s[i].y1==s[i].y2){
            int x1=s[i].x1,x2=s[i].x2;
            for(int j=min(x1,x2);j<=max(x1,x2);j++){
                mp[j][s[i].y1]++;
            }
        }
    }
}
int tx[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void bfs(int x,int y,int flag){

    queue<pair<int,int>>Q;
    Q.push(make_pair(x,y));
    while(!Q.empty()){
        pair<int,int>u;
        u=Q.front(); Q.pop();
        a[u.first][u.second]=flag;
        for(int i=0;i<4;i++){
            int dx=tx[i][0]+u.first;
            int dy=tx[i][1]+u.second;
            if(dx<1||dx>n||dy<1||dy>m) continue;
            if(!vis[dx][dy]&&!mp[dx][dy]){
                vis[dx][dy]=1;
                Q.push(make_pair(dx,dy));
            }
        }
    }
}

int anss=0,anx[maxn*10];
int fin(int x){
    return b[x]==x?x:b[x]=fin(b[x]);
}
void solve(){

    anss=top;
    for(int i=p;i>=1;i--){
        anx[i]=anss;
        if(s[i].x1==s[i].x2){
            int y1=s[i].y1,y2=s[i].y2;
            for(int j=min(y1,y2);j<=max(y1,y2);j++){
                mp[s[i].x1][j]--;
                if(!mp[s[i].x1][j]) a[s[i].x1][j]=++top,anss++;
            }
            for(int j=min(y1,y2);j<=max(y1,y2);j++){
                if(mp[s[i].x1][j])  continue;
                int fx=fin(a[s[i].x1][j]);
                for(int k=0;k<4;k++){
                    int dx=tx[k][0]+s[i].x1;
                    int dy=tx[k][1]+j;
                    if(dx<1||dx>n||dy<1||dy>m) continue;
                    if(!mp[dx][dy]){
                        int fy=fin(a[dx][dy]);
                        if(fx!=fy){
                            b[fy]=fx;
                            anss--;
                        }
                    }
                }
            }
        }
        else if(s[i].y1==s[i].y2){
            int x1=s[i].x1,x2=s[i].x2;
            for(int j=min(x1,x2);j<=max(x1,x2);j++){
                mp[j][s[i].y1]--;
                if(!mp[j][s[i].y1]) a[j][s[i].y1]=++top,anss++;
            }
            for(int j=min(x1,x2);j<=max(x1,x2);j++){
                if(mp[j][s[i].y1])  continue;
                int fx=fin(a[j][s[i].y1]);
                for(int k=0;k<4;k++){
                    int dx=tx[k][0]+j;
                    int dy=tx[k][1]+s[i].y1;
                    if(dx<1||dx>n||dy<1||dy>m) continue;
                    if(!mp[dx][dy]){
                        int fy=fin(a[dx][dy]);
                        if(fx!=fy){
                            b[fy]=fx;
                            anss--;
                        }
                    }
                }
            }
        }
    }
}
int main()
{
    scanf("%d %d %d",&n,&m,&p);
    for(int i=1;i<=p;i++){
        scanf("%d %d %d %d",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2);
    }
    init();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){

            if(!mp[i][j]&&!vis[i][j]){
                ++top;
                bfs(i,j,top);
            }
        }
    }

    solve();

    for(int i=1;i<=p;i++) printf("%d\n",anx[i]);
    return 0;
}

 

 类似资料: