• 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 }

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

  • 相关阅读:
    Git 远程分支的查看及相关问题
    Clean Code – Chapter 6 Objects and Data Structures
    Clean Code – Chapter 5 Formatting
    Clean Code – Chapter 4: Comments
    利用 SerialPort 控件实现 PC 串口通信
    Clean Code – Chapter 3: Functions
    oracle如何查看当前有哪些用户连接到数据库
    c++ Ansi和Unicode相互转换
    c++ Utf8和Unicode相互转换
    c++ 根据某个字符或者字符串分割另外一个字符串
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3052314.html
Copyright © 2020-2023  润新知