zoukankan      html  css  js  c++  java
  • 湖南大学ACM程序设计新生杯大赛(同步赛)J

    题目描述

    Once there was a pig, which was very fond of treasure hunting. One day, when it woke up, it found itself in a strange land of treasure. As for how to come in, or how to go out, no ways to know. Sad.

    The good news is, it was lucky that it got the treasure map.

    But there is a bad news too, this map is an encrypted map.

    You can think of it as a matrix of R*C. Each grid is a number of Hexadecimal(十六进制), that is the number is between {‘0’,’1’,…’9’,’A’,’B’,…,’F’}, and the 4 length Binary number(4位二进制数) corresponding is the real treasure map.

    For example, the number '0' on the encrypted graph represents the actual map ‘0000’, and '1' represents the actual map ‘0001’, ... The 'A' represents the actual map ‘1010’, and 'F' represents the actual map ‘1111’.

    The owner of the treasure is very clever, he build some insuperable wall in the treasure to avoid stealing, we use ‘0’ to describe it. Obviously ‘1’ indicated that this grid bury exactly one diamond.

    The pig can only walk up to four adjacent squares in the upper, lower, left and right directions at a time. Wherever it goes, it will dig out the diamond in this grid(if there is diamond buried in the grid) and put the diamond in its own package.

    Though it has got the map, but doesn't know where it is in the peach blossom trap now, that means it could be at any ‘.’ in the matrix. It finds you smart to tell it how many diamonds it will get at most.

    输入描述:

    Multiple groups of test case. (no more than 10 groups. )
    The first line of each group contains two numbers R and C,(0<=R, C<=3000), representing the number of rows and the number of columns of peach blossom trap, respectively. Stop the program when R and C are both 0.
    Then there are next R lines, each line contains C characters, describe as above.
    It is guarantee all the input is legal.

    输出描述:

    For each test case, output the answer on each line, representing the most number of diamonds can be obtained by the pig.
    示例1

    输入

    5 2
    E8
    23
    52
    78
    01
    
    3 1
    0
    4
    0
    
    0 0

    输出

    6
    1

    说明

    In the first example, the real treasure map is:
    11101000
    00100011
    01010010
    01111000
    00000001
    So it is possible to dig out 6 diamonds at most.

    题解

    $bfs$,压位。

    主要是要想办法省内存,$01$矩阵可以压位,每$32$位$01$串拿一个$int$表示即可。

    然后就是普通的$bfs$,队列的内存峰值也只有$1000$个位置的数量级。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 3000 + 10;
    int r, c;
    char s[maxn];
    unsigned int m[maxn][450];
    int f[maxn * 4];
    int st[maxn], cnt;
    
    int dir[4][2] = {
      {-1, 0},
      {1, 0},
      {0, -1},
      {0, 1},
    };
    
    int out(int x, int y) {
      if(x < 0 || x >= r) return 1;
      if(y < 0 || y >= 4 * c) return 1;
      return 0;
    }
    
    int Get(int x, int y) {
      unsigned int p = (unsigned)(1 << (y % 32));
      if(m[x][y / 32] & p) return 1;
      return 0;
    }
    
    void Set(int x, int y) {
      unsigned int p = (unsigned)(1 << (y % 32));
      m[x][y / 32] = m[x][y / 32] ^ p;
    }
    
    int main() {
      while(~scanf("%d%d", &r, &c)) {
        if(r == 0 && c == 0) break;
        for(int i = 0; i < r; i ++) {
          for(int j = 0; j < 400; j ++) {
            m[i][j] = 0;
          }
        }
        for(int i = 0; i < r; i ++) {
          scanf("%s", s);
          int sz = 0;
          for(int j = 0; j < c; j ++) {
            int num;
            if(s[j] >= '0' && s[j] <= '9') num = s[j] - '0';
            else num = s[j] - 'A' + 10;
    
            cnt = 0;
            for(int k = 0; k < 4; k ++) {
              st[cnt ++] = (num & (1 << k)) ? 1 : 0;
            }
            for(int k = 3; k >= 0; k --) {
              f[sz ++] = st[k];
            }
          }
          for(int j = 0; j < sz; j ++) {
            m[i][j / 32] = m[i][j / 32] + (unsigned)(f[j] * (1 << (j % 32)));
          }
        }
    
        int ans = 0;
    
        for(int i = 0; i < r; i ++) {
          for(int j = 0; j < 4 * c; j ++) {
            if(Get(i, j) == 0) continue;
            int sum = 0;
            queue<int> Q;
            Q.push(i * 4 * c + j);
            Set(i, j);
            while(!Q.empty()) {
              int h = Q.front();
              int x = h / (4 * c);
              int y = h % (4 * c);
              Q.pop();
              sum ++;
              for(int i = 0; i < 4; i ++) {
                int tx = x + dir[i][0];
                int ty = y + dir[i][1];
                if(out(tx, ty)) continue;
                if(Get(tx, ty) == 0) continue;
                Q.push(tx * 4 * c + ty);
                Set(tx, ty);
              }
            }
            ans = max(ans, sum);
            if(ans > r*c*2) break;
          }
          if(ans > r*c*2) break;
        }
    
        printf("%d
    ", ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    优麒麟(UbuntuKylin)不是国产Linux操作系统
    Win10開始菜单打不开
    五步让你玩转CocoaPods
    设计模式学习笔记之适配器模式
    感谢各位亲们的大力支持,免费的HTML5学习课程《HTML5网页开发实例具体解释》连载已经结束了!
    iOS获取时间、日期
    leetcode NO.1 两数之和 (python3实现)
    leetcode NO.53 最大子序列和 (python3实现)
    [笔记]《算法图解》第六章 广度搜索优先
    [笔记]《算法图解》第四章 快速排序
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8108573.html
Copyright © 2011-2022 走看看