• USACO4.4 重叠的图像 Frame Up


    题目链接

    Solution

    今天上午测试题...最后几分钟才看到要输出所有解,于是爆成了 44pts...

    根据输入可以得到所有字母构成的矩形。如果字符 (i) 出现在了字符 (j) 的矩形上,那么 (i) 的图像一定在 (j) 的图像上方,从 (j)(i) 连边。

    跑一个拓扑排序,每次可以选的是队列里所有点之一。因此需要 dfs 所有可能情况,最后存到变量里按照字典序输出。

    手写队列要注意,不能直接对队列排序,dfs 时会造成混乱。

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 2333;
    char a[N][N];
    int n, m, Num = 0, tot = 0, res = 0;
    int vis[N], lx[N], rx[N], ly[N], ry[N], e[N][N];
    int q[N], du[N], use[N];
    string ans[2333333];
    
    void dfs(int num, int stp)
    {
        if(stp == Num)
        {
            res++;
            ans[res] = "";
            for(int i = 1; i <= stp; i++) ans[res] += (char)(use[i]);
            return ;
        }
        for(int i = 1; i <= num; i++)
        {
            int x = q[i], cnt = num - 1;
            for(int j = i; j < num; j++) q[j] = q[j + 1];
            for(int j = 'A'; j <= 'Z'; j++)
            {
                if(vis[j] && e[x][j])
                {
                    du[j]--;
                    if(du[j] == 0) q[++cnt] = j;
                }
            }
            use[stp + 1] = x;
            dfs(cnt, stp + 1);
            for(int j = num; j > i; j--) q[j] = q[j - 1];
            q[i] = x;
            for(int j = 'A'; j <= 'Z'; j++)
                if(vis[j] && e[x][j]) du[j]++;
        }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(e, 0, sizeof(e));
        memset(lx, 0x3f, sizeof(lx));
        memset(ly, 0x3f, sizeof(ly));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                cin >> a[i][j];
                if(a[i][j] >= 'A' && a[i][j] <= 'Z')
                {
                    if(!vis[a[i][j]])
                    {
                        vis[a[i][j]] = 1;
                        Num++;
                    }
                    lx[a[i][j]] = min(lx[a[i][j]], i);
                    ly[a[i][j]] = min(ly[a[i][j]], j);
                    rx[a[i][j]] = max(rx[a[i][j]], i);
                    ry[a[i][j]] = max(ry[a[i][j]], j);
                }
            }
        for(int i = 'A'; i <= 'Z'; i++)
        {
            if(!vis[i]) continue;
            for(int j = ly[i]; j <= ry[i]; j++)
            {
                char ch1 = a[lx[i]][j], ch2 = a[rx[i]][j];
                if(vis[ch1] && ch1 != i) e[i][ch1] = 1;
                if(vis[ch2] && ch2 != i) e[i][ch2] = 1;
            }
            for(int j = lx[i]; j <= rx[i]; j++)
            {
                char ch1 = a[j][ly[i]], ch2 = a[j][ry[i]];
                if(vis[ch1] && ch1 != i) e[i][ch1] = 1;
                if(vis[ch2] && ch2 != i) e[i][ch2] = 1;
            }
        }
        memset(du, 0, sizeof(du));
        for(int i = 'A'; i <= 'Z'; i++)
        {
            if(!vis[i]) continue;
            for(int j = 'A'; j <= 'Z'; j++)
            {
                if(!vis[j]) continue;
                if(e[i][j] == 1) du[j]++;
            }
        }
        for(int i = 'A'; i <= 'Z'; i++)
        {
            if(!vis[i]) continue;
            if(du[i] == 0)
            {
                tot++;
                q[tot] = i;
            }
        }
        dfs(tot, 0);
        sort(ans + 1, ans + res + 1);
        for(int i = 1; i <= res; i++) cout << ans[i] << endl;
        return 0;
    }
    
  • 相关阅读:
    Windows2012下安装和配置Oracle BIEE12c
    Windows Oracle 12安装教程
    SpringCloud学习之Ribbon使用(四)
    SpringCloud学习之手把手教你用IDEA搭建入门项目(三)
    SpringCloud学习之手把手教你用IDEA搭建入门项目(二)
    SpringCloud学习之手把手教你用IDEA搭建入门项目(一)
    SpringCloud学习之手把手教你用IDEA搭建入门项目【番外篇】(一)
    SpringCloud学习之大纲总略(大纲篇)
    Websocket @serverendpoint 404
    XMLHttpRequest status为0
  • 原文地址:https://www.cnblogs.com/Andy-park/p/14056530.html
Copyright © 2020-2023  润新知