zoukankan      html  css  js  c++  java
  • poj2585&&zoj2193 Window Pains ——拓扑排序入门题

    题目链接:http://poj.org/problem?id=2585  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2193

    题目大意:

      有9个窗口,每个窗口占4个格子,并且每个窗口的位置是固定的。如果重叠的话,在前面的窗口会覆盖另一种窗口,这9个窗口在4*4的矩阵里面,给出一种矩阵的格局。问这中格局是不是合法的。

    题目思路:

      还是看的书上的。刚开始一点也没有思路。方法就是:16个格子,每个格子可能会存在哪几种窗口,这是可以枚举出来的。针对输入的矩阵,那么可以判断,每一个格子会覆盖哪几种窗口,如果这种窗口在16个格子里面出现过,那么就可以判断当前这个格子一定覆盖了它,那么就可以用一条有向边连接当前窗口和被覆盖的窗口。这样,就可以得到一个图。在16个格子里面没有出现过的窗口我们可以不考虑。得到有向图后,发现,如果存在一个有向环,那么就一定是不合理的,因为这表明,一种窗口A覆盖了另一种窗口B,同时B又覆盖了A,这是不可能的。所以这个矩阵就是不合法的。反之,如果不存在有向环,就是合法的。这样,就转化为用拓扑排序判断环的问题了。先建图,再判断环。

    写了两遍,其中出现各种BUG……

    第一遍:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 string cover[4][4];
    23 int a[10][10];bool g[10][10];int id[10];
    24 map<int, bool>mymap;
    25 
    26 int main(void){
    27 #ifndef ONLINE_JUDGE
    28   freopen("poj2585.in", "r", stdin);
    29 #endif
    30   int i, j, k;
    31   for (i = 0; i < 4; ++i) for (j = 0; j < 4; ++j)
    32   cover[i][j].erase();
    33   for (k = 1; k <= 9; ++k) {
    34     i = (k - 1) / 3; j = (k - 1) % 3;
    35     cover[i][j] += (k + '0');
    36     cover[i][j+1] += (k + '0');
    37     cover[i+1][j] += (k + '0');
    38     cover[i+1][j+1] += (k + '0');
    39   }
    40   string s; int t = 0;
    41   while (cin >> s) {
    42     mymap.clear();
    43     for (i = 0; i < 10; ++i)
    44     {
    45       id[i] = 0;
    46       for (j= 0; j < 10; ++j)
    47       {
    48         g[i][j] = false; a[i][j] = 0;
    49       }
    50     } t = 0;
    51     if (s == "ENDOFINPUT") break;
    52     for (i = 0; i < 4; ++i) {
    53       for (j = 0; j < 4; ++j) {
    54         scanf("%d", &k); a[i][j] = k;
    55         if (mymap[k] == false) { mymap[k] = true; t++; }
    56       }
    57     }
    58     for (i = 0; i < 4; ++i) {
    59       for (j = 0; j < 4; ++j) {
    60         for (int p = 0; p < cover[i][j].length(); ++p) {
    61           if (g[a[i][j]][cover[i][j][p] -'0'] == false && a[i][j]!=cover[i][j][p] -'0' && mymap[cover[i][j][p]-'0'] ) {
    62             g[a[i][j]][cover[i][j][p] -'0'] = true; id[cover[i][j][p]-'0' ]++;
    63           }
    64         }
    65       }
    66     }
    67     bool flag = true;
    68     for (i = 0; i < t; ++i) {
    69       k = 1;
    70       while (!(mymap[k]&&id[k]==0) && (k <= 9)) k++;
    71       if (k > 9) {flag = false; break; }
    72       mymap[k] = false;
    73       for (j = 1; j <= 9; ++j) {
    74         if (g[k][j] == true && mymap[j] ) id[j]--;
    75       }
    76     }
    77     if (flag) cout << "THESE WINDOWS ARE CLEAN" << endl;
    78     else cout << "THESE WINDOWS ARE BROKEN" << endl;
    79     cin >> s;
    80   }
    81 
    82   return 0;
    83 }

    第二遍:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 string cover[4][4] = { "1", "12", "23", "3", "14", "1245", "2356", "36",
    23  "47", "4578", "5689", "69", "7", "78", "89", "9"};
    24 bool edge[10][10];
    25 int a[10][10];
    26 map<int, bool>mymap;
    27 int mystack[10], Count[10];
    28 int main(void){
    29 #ifndef ONLINE_JUDGE
    30   freopen("poj2585.in", "r", stdin);
    31 #endif
    32   string s; int i, j, k;
    33   while (cin >> s) {
    34     if (s == "ENDOFINPUT") break;
    35     mymap.clear(); memset(edge, false, sizeof(edge));
    36     int kind = 0;
    37     for (i = 0; i < 10; ++i) {
    38       Count[i] = mystack[i] = 0;
    39     }
    40     for (i = 0; i < 4; ++i) {
    41       for (j = 0; j < 4; ++j) {
    42         scanf("%d", &a[i][j]);
    43         if (!mymap[a[i][j] ]) {
    44           mymap[a[i][j] ] = true; kind++;
    45         }
    46       }
    47     }
    48     for (i = 0; i < 4; ++i) {
    49       for (j = 0; j < 4; ++j) {
    50         for (int p = 0; p < cover[i][j].length(); ++p) {
    51           int nu = cover[i][j][p] - '0';
    52           if (mymap[nu] &&  edge[a[i][j] ][nu ]==false && nu != a[i][j] ) {
    53             edge[a[i][j] ][nu] = true; Count[nu]++;
    54           }
    55         }
    56       }
    57     }
    58     int top = 0, cnt = 0;
    59     for (i = 1; i <= 9; ++i) {
    60       if (Count[i] == 0 && mymap[i]) mystack[++top] = i;
    61     }
    62     while (top != 0) {
    63       int fo = mystack[top]; Count[fo] = -1;
    64       top--; cnt++;
    65       for (i = 1; i <= 9; ++i) {
    66         if (edge[fo][i] == true && mymap[i]) {
    67           Count[i]--;
    68         }
    69       }
    70       if (!top) // 这个地方,调试很久。不能重复入栈!也就是说,除非栈空了,否则,不要扫描。
    71       for (i = 1; i <= 9; ++i) {
    72         if (Count[i] == 0 && mymap[i]) mystack[++top] = i;
    73       }
    74     }
    75     if (cnt < kind) cout << "THESE WINDOWS ARE BROKEN\n";
    76     else cout << "THESE WINDOWS ARE CLEAN\n";
    77     cin >> s;
    78   }
    79 
    80   return 0;
    81 }

    细节,很重要。还有,书上的代码貌似有错误……

  • 相关阅读:
    03_ if 练习 _ little2big
    uva 11275 3D Triangles
    uva 12296 Pieces and Discs
    uvalive 3218 Find the Border
    uvalive 2797 Monster Trap
    uvalive 4992 Jungle Outpost
    uva 2218 Triathlon
    uvalive 3890 Most Distant Point from the Sea
    uvalive 4728 Squares
    uva 10256 The Great Divide
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3052314.html
Copyright © 2011-2022 走看看