zoukankan      html  css  js  c++  java
  • CF-Codeforces Round #639 (Div. 2)-D-Monopole Magnets

    题目传送门

    sol:有三种情况无法构造满足条件的答案。

    1. 出现同一行(列)的两个'#'之间隔着一段'.'的情况,比如样例2。如果两个'#'之间隔着一段'.',那么在这一行(列)就无法放置南磁铁,因为'#'代表北磁铁可以到达,若在这一行(列)任意位置放置南磁铁,会导致这两个'#'中的至少一个北磁铁被吸到中间的'.'部分。这是违反第三条规则的。
    2. 每一列都出现过至少一个北磁铁,同时还有全是'.'的行出现,比如样例4,。样例4中只有一列,在这一列中出现了'#',同时第一行全都是'.',这将导致第一行无法放置南磁铁,因为在这一行的任意位置放置南磁铁都会将对应列'#'中的北磁铁吸到这一行的'.',这同样是违反第三条规则的。
    3. 根据第二种情况可以得出,如果每一行都出现过至少一个北磁铁,同时还有全是'.'的列出现。也是无法构造满足条件的答案的。例子就是样例4旋转90度。这会导致全是'.'的列无法放置南磁铁。

       除了上述三种情况,必能构造合法答案。如果,某一行(列)中出现了'#'那就在'#'里面放置南磁铁,可以在所有'#'里面都放置一个南磁铁。如果这一行(列)中没有出现过'#',就找一个没有出现过'#'的列(行)放置南磁铁。比如样例3中第一行第五列的'#'变成了'.'那第一行的南磁铁依然放在第五列,因为第五列将没有'#'。最终需要的北磁铁的数量就是联通块的数量。

    • 深度优先搜索
      #include <bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      typedef pair<int, int> PII;
      const int MAXN = 1010;
      char mp[MAXN][MAXN];
      inline int read() {
          int n = 0, f = 1; char c = getchar();
          while (c < '0' || c > '9') {
              if (c == '-') f = -f;
              c = getchar();
          }
          while (c >= '0' && c <= '9') {
              n = 10 * n + (c ^ '0');
              c = getchar();
          }
          return f * n;
      }
      void dfs(int i, int j) {
          mp[i][j] = '.';
          if (mp[i + 1][j] == '#') dfs(i + 1, j);
          if (mp[i][j + 1] == '#') dfs(i, j + 1);
          if (mp[i - 1][j] == '#') dfs(i - 1, j);
          if (mp[i][j - 1] == '#') dfs(i, j - 1);
      }
      int main() {
          int n = read(), m = read();
          for (int i = 1; i <= n; i++) scanf("%s", mp[i] + 1);
          int row = 0, col = 0; bool has = 1;
          // 找有多少个行出现过'#'
          for (int i = 1; i <= n; i++) {
              bool ok = 0;
              for (int j = 1; j <= m; j++) {
                  if (mp[i][j] == '#') {
                      ok = 1;
                      break;
                  }
              }
              row += ok;
          }
          // 找有多少个列出现过'#'
          for (int j = 1; j <= m; j++) {
              bool ok = 0;
              for (int i = 1; i <= n; i++) {
                  if (mp[i][j] == '#') {
                      ok = 1;
                      break;
                  }
              }
              col += ok;
          }
          for (int i = 1; i <= n; i++) {
              int l = -1, r = -1;
              for (int j = 1; j <= m; j++) {
                  if (mp[i][j] == '#') {
                      if (l != -1) r = j;
                      else l = r = j;
                  }
              }
              // 这一行没有'#'同时每一行都出现过'#',则无法构造合法解
              if (l == -1) {
                  if (col == m) has = 0;
                  continue;
              }
              // 找是否有某行两个'#'之间出现'.'
              for (int j = l; j <= r; j++) {
                  if (mp[i][j] != '#') {
                      has = 0;
                      break;
                  }
              }
          }
          for (int j = 1; j <= m; j++) {
              int l = -1, r = -1;
              for (int i = 1; i <= n; i++) {
                  if (mp[i][j] == '#') {
                      if (l != -1) r = i;
                      else l = r = i;
                  }
              }
              // 这一列没有'#'同时每一行都出现过'#',则无法构造合法解
              if (l == -1) {
                  if (row == n) has = 0;
                  continue;
              }
              // 找是否有某列两个'#'之间出现'.'
              for (int i = l; i <= r; i++) {
                  if (mp[i][j] != '#') {
                      has = 0;
                      break;
                  }
              }
          }
          if (has == 0) return 0 * puts("-1");
          int ans = 0;
          // dfs找联通块
          for (int i = 1; i <= n; i++) {
              for (int j = 1; j <= m; j++) {
                  if (mp[i][j] == '#') dfs(i, j), ans ++;
              }
          }
          printf("%d
      ", ans);
          return 0;
      }

      ------------------------------------------------------------分隔线------------------------------------------------------------

      总结:这种题型好像做的不多,这题也算印象深刻了,考虑到了第二种无解情况居然忽略了第三种无解情况。评测机还挂了不给评测结果。这场居然urt了,不然应该就上紫了,想上个紫好难啊!!!

  • 相关阅读:
    用RBG颜色设置自定义颜色
    Swift UI
    SVN上传代码时代码失败
    coredata中谓词的使用
    Core Data的使用(二)备
    CoreData (四)备
    CoreData (三)备
    CI框架篇之模型篇--直接操作(2)
    CI框架篇之模型篇--初识(1)
    CI框架篇之视图篇--载入(1)
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/12842681.html
Copyright © 2011-2022 走看看