• ZOJ 3780 Paint the Grid Again


    拓扑排序。2014浙江省赛题。

    先看行:

    如果这行没有黑色,那么这个行操作肯定不操作。

    如果这行全是黑色,那么看每一列,如果列上有白色,那么这一列连一条边到这一行,代表这一列画完才画那一行

    如果不全是黑色,那么看这一行的每一个元素,如果有白色的,那么白色所在列向这一行连边。

    再看列:

    与看行类似,不再赘述。

    建图建完之后进行拓扑排序。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    const int maxn = 500 + 10;
    int T, n;
    char s[maxn][maxn];
    int G[2 * maxn][2 * maxn];
    vector<int>g[2 * maxn];
    bool flag[2 * maxn];
    int tot[2 * maxn];
    int w[maxn], b[maxn];
    struct cmp{
        bool operator ()(int &a, int &b){
            return a>b;//最小值优先
        }
    };
    priority_queue<int, vector<int>, cmp>Q;//最小值优先
    vector<int>ans;
    
    void init()
    {
        memset(G, -1, sizeof G);
        for (int i = 0; i <= 2 * n; i++) g[i].clear();
        memset(flag, 1, sizeof flag);
        memset(tot, 0, sizeof tot);
        while (!Q.empty()) Q.pop();
        ans.clear();
        for (int i = 0; i<n; i++)
        {
            int sum = 0;
            for (int j = 0; j<n; j++) if (s[i][j] == 'X') sum++;
            b[i] = sum;
        }
    
        for (int j = 0; j<n; j++)
        {
            int sum = 0;
            for (int i = 0; i<n; i++) if (s[i][j] == 'O') sum++;
            w[j] = sum;
        }
    }
    
    void read()
    {
        scanf("%d", &n);
        for (int i = 0; i<n; i++) scanf("%s", s[i]);
    }
    
    void work()
    {
        for (int i = 0; i<n; i++)
        {
            if (b[i] == 0) flag[i + n] = 0;
            else if (b[i] == n)
            {
                for (int j = 0; j<n; j++) if (w[j]) G[j][i + n] = 1;
            }
            else
            {
                for (int j = 0; j<n; j++) if (s[i][j] == 'O') G[i + n][j] = 1;
            }
        }
    
        for (int j = 0; j<n; j++)
        {
            if (w[j] == 0) flag[j] = 0;
            else if (w[j] == n)
            {
                for (int i = 0; i<n; i++) if (b[i]) G[i + n][j] = 1;
            }
            else
            {
                for (int i = 0; i<n; i++) if (s[i][j] == 'X') G[j][i + n] = 1;
            }
        }
    
        for (int x = 0; x<2 * n; x++)
        for (int y = 0; y<2 * n; y++)
        if (G[x][y] == 1)
        {
            tot[y]++; g[x].push_back(y);
        }
    
    
        for (int i = 0; i<2 * n; i++) if (flag[i] && tot[i] == 0) Q.push(i);
    
        while (!Q.empty())
        {
            int top = Q.top(); Q.pop();
            ans.push_back(top);
            for (int i = 0; i<g[top].size(); i++) {
                tot[g[top][i]]--;
                if (tot[g[top][i]] == 0) Q.push(g[top][i]);
            }
        }
    
        if (ans.size()<n) printf("No solution
    ");
        else
        {
            for (int i = 0; i<ans.size(); i++)
            {
                if (ans[i] >= 0 && ans[i] <= n - 1) printf("C%d", ans[i] + 1);
                else printf("R%d", ans[i] - n + 1);
    
                if (i<ans.size() - 1) printf(" ");
                else printf("
    ");
            }
        }
    
    }
    
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            read();
            init();
            work();
        }
        return 0;
    }
  • 相关阅读:
    Android_程序未处理异常的捕获与处理
    instanceof关键字
    乐优商城项目爬坑
    [LeetCode]Isomorphic Strings
    [LeetCode]Contains Duplicate II
    [LeetCode]Valid Sudoku
    [LeetCode]Valid Anagram
    [LeetCode]Contains Duplicate
    [LeetCode]Single Number
    [LeetCode]Valid Number
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5201082.html
Copyright © 2020-2023  润新知