zoukankan      html  css  js  c++  java
  • Artwork Gym

    题目

      https://cn.vjudge.net/contest/323505#problem/A

    题意

      给出一个m×n的矩阵,一开始全是白色,然后给出q次操作,每次将(x1,y1)到(x2,y2)这宽度为1的区域涂黑。输出每次涂黑操作后白色可以分成多少块。

    题解

      一开始从各种方向去想BFS的优化QAQ,后来才知道是一道并查集的题目。我们可以反向思考,先将每次涂黑的操作进行完毕,每次给涂黑的地方+1,然后把最后状态的白色块用并查集连到一起。那么我们反向删除黑色部分,当删除的这一块权值变为0时,意味着这一块从黑变成白了,那么我们先将其当作独立的一块,记录num++,然后去跑这一点的上下左右,如果两点分属不同的集合,那么num--,并且将外面的点以当前点为父亲连入。每次操作后记录下来答案,最后输出即可。学到了学到了qwq

     #include <iostream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <map>
    #include <bitset>
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define lowbit(x) (x&(-x))
    #define MID (l + r) / 2
    #define ll long long
    
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll mod = 1e6 + 3;
    const int maxn = 1e4 + 7;
    const int N = 1010;
    
    struct Que {
        int x1, x2, y1, y2;
    }que[maxn];
    
    int MAP[N][N];
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    int f[1000100];
    int vis[1000100];
    int res[1000100];
    
    int Find(int i) {return f[i] = (f[i] == i) ? f[i] : f[i] = Find(f[i]);}
    
    int main() {
        int n, m, q;
        cin >> m >> n >> q;
        for(int i = 1; i <= n*m+2; i++) f[i] = i;
        for(int i = 1; i <= q; i++) {
            cin >> que[i].y1 >> que[i].x1 >> que[i].y2 >> que[i].x2;
            if(que[i].x1 == que[i].x2) {
                int t1 = min(que[i].y1, que[i].y2);
                int t2 = max(que[i].y1, que[i].y2); 
                for(int j = t1; j <= t2; j++) MAP[que[i].x1][j]++;
            }
            else {
                int t1 = min(que[i].x1, que[i].x2);
                int t2 = max(que[i].x1, que[i].x2);
                for(int j = t1; j <= t2; j++) MAP[j][que[i].y1]++;
            }
        }
        // for(int i = 1; i <= n; i++) {
        //     for(int j = 1; j <= m; j++) {
        //         cout << MAP[i][j] << ' ';
        //     }
        //     cout << endl;
        // }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(!MAP[i][j]) {
                    int id = (i-1)*m+j;
                    for(int k = 0; k < 4; k++) {
                        int x = i+dx[k];
                        int y = j+dy[k];
                        if(x < 1 || x > n) continue;
                        if(y < 1 || y > m) continue;
                        if(!MAP[x][y]) {
                            int t = (x-1)*m+y;
                            int fi = Find(id);
                            int fo = Find(t);
                            f[fo] = fi;
                        }
                    }
                }
            }
        }
        int num = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                int fi = Find((i-1)*m+j);
                if(!MAP[i][j] && !vis[fi]) {
                    vis[fi] = 1;
                    num++;
                }
            }
        }
        for(int i = q; i >= 1; i--) {
            res[i] = num;
            if(que[i].x1 == que[i].x2) {
                int t1 = min(que[i].y1, que[i].y2);
                int t2 = max(que[i].y1, que[i].y2); 
                for(int j = t1; j <= t2; j++) {
                    MAP[que[i].x1][j]--;
                    if(!MAP[que[i].x1][j]) {
                        num++;
                        int id = (que[i].x1-1)*m+j;
                        for(int k = 0; k < 4; k++) {
                            int x = que[i].x1+dx[k];
                            int y = j+dy[k];
                            if(x < 1 || x > n) continue;
                            if(y < 1 || y > m) continue;
                            if(!MAP[x][y]) {
                                int t = (x-1)*m+y;
                                int fi = Find(id);
                                int fo = Find(t);
                                if(fi != fo) num--;
                                f[fo] = fi;
                            }
                        }
                    }
                }
            }
            else {
                int t1 = min(que[i].x1, que[i].x2);
                int t2 = max(que[i].x1, que[i].x2);
                for(int j = t1; j <= t2; j++) {
                    MAP[j][que[i].y1]--;
                    if(!MAP[j][que[i].y1]) {
                        num++;
                        int id = (j-1)*m+que[i].y1;
                        for(int k = 0; k < 4; k++) {
                            int x = j+dx[k];
                            int y = que[i].y1+dy[k];
                            if(x < 1 || x > n) continue;
                            if(y < 1 || y > m) continue;
                            if(!MAP[x][y]) {
                                int t = (x-1)*m+y;
                                int fi = Find(id);
                                int fo = Find(t);
                                if(fi != fo) num--;
                                f[fo] = fi;
                            }
                        }
                    }
                }
            }
        }
        for(int i = 1; i <= q; i++) cout << res[i] << endl;
        return 0;
    }
  • 相关阅读:
    PyQt作品 – PingTester – 多点Ping测试工具
    关于和技术人员交流的一二三
    Pyjamas Python Javascript Compiler, Desktop Widget Set and RIA Web Framework
    Hybrid Qt applications with PySide and Django
    pyjamas build AJAX apps in Python (like Google did for Java)
    PyQt 维基百科,自由的百科全书
    InfoQ:请问为什么仍要选择Java来处理后端的工作?
    Eric+PyQt打造完美的Python集成开发环境
    python select module select method introduce
    GUI Programming with Python: QT Edition
  • 原文地址:https://www.cnblogs.com/Ruby-Z/p/11455786.html
Copyright © 2011-2022 走看看