• HDOJ 5335 Walk Out 【bfs 贪心 斜行dp】


    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5335


    题目就是在一个只有0 1 的矩阵里从左上角走到右下角
    每走一步记录当前的坐标值 输出所有结果中数值最小的结果 输出时去掉前缀零。
    很明显如果有全部是0的部分,直接输出0就可以了
    前面不管有多少个0都是可以去掉的
    从1开始之后,数字的长度就固定了
    而长的数总比短的数大
    所以先bfs只走0走到最深处
    之后贪心,如果下一步可以走0就走0,走到最后输出即可


    实现的细节是如果开始是1的话就可以不必进入bfs
    以及bfs如果可以到达右下角的出口就可以直接输出0
    (注意只有一个数据的情况,如果是0。。。)
    其他的情况先将最右下角可以到达的0都标记成可以达到
    之后按照层数(layer = i+j) 依次递增找到周围可达的下一个点(只走右边或者下边)如果有0就改变标记,之后只走符合标程的下一个位置即可。


    每一层的结点其实找起来也比较恶心……
    代码最后有一些样例……送给泥萌……不谢……

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 using namespace std;
      6 #define clr(c, x) memset(c, x, sizeof(c));
      7 const int INF = 0x3f3f3f3f;
      8 typedef struct point{
      9     int x, y;
     10     bool operator < (const point& p) const{
     11         if(x == p.x) return y < p.y; // 先按照行比较大小,行相同按照列比较大小
     12         else return x < p.x;
     13     }
     14     bool operator > (const point& p) const { return p < *this; }
     15 }p;
     16 int dirx[4] = {0, 1, 0, -1};
     17 int diry[4] = {1, 0, -1, 0};
     18 const int MAXL = 1005;
     19 char maze[MAXL][MAXL];
     20 int T, n, m;
     21 int step[MAXL][MAXL]; // bfs
     22 queue<p> q;
     23 p start, goal, startDfs;
     24 int x, y, xx, yy; // x,y current; xx,yy next;
     25 int stepDfs;
     26 char ans[MAXL*MAXL+1];
     27 bool unlock[MAXL][MAXL];
     28 bool subflag;
     29 int layer;
     30 
     31 bool Inside(int xx, int yy){ // 越界判断
     32     if(xx >= 0 && xx < n && yy >= 0 && yy < m) return true;
     33     else return false;
     34 }
     35 
     36 void bfs(){ // 连续走0
     37     layer = 0;
     38     start.x = 0, start.y = 0;
     39     p current, next;
     40     clr(step, 0);
     41     while(!q.empty()) q.pop();
     42     subflag = true;
     43     step[0][0] = 1;
     44     if(maze[0][0] == '1'){
     45             subflag = false;
     46             return; // 起点就为1时就不必bfs了
     47     }
     48     q.push(start);
     49 
     50     while(!q.empty()){
     51         current = q.front();
     52         x = current.x, y = current.y;
     53         layer = layer > (x+y) ? layer : (x+y);
     54         for(int i = 0; i < 4; i++){
     55             xx = x + dirx[i], yy = y + diry[i];
     56             if(Inside(xx, yy) && maze[xx][yy] == '0' && step[xx][yy] == false){
     57                 next.x = xx, next.y = yy;
     58                 step[xx][yy] = step[x][y] + 1;
     59                 q.push(next);
     60             }
     61         }
     62         q.pop();
     63     }
     64     return;
     65 }
     66 
     67 void Result(){
     68     p current, next;
     69     clr(ans, '1');
     70     clr(unlock, 0);
     71     if(layer == n-1+m-1 && maze[0][0] == '0'){ // 如果有一条路可以走到终点且全为0
     72         puts("0"); // 只输出一个0
     73         return;
     74     }
     75     int X, Y;
     76     for(X = 0; X < n; X++){
     77         if(layer-X >= 0 && layer-X < m){
     78             Y= layer - X;
     79             if(step[X][Y] != 0){
     80                 unlock[X][Y] = true;
     81                 ans[layer] = maze[X][Y];
     82             }
     83         }
     84     }
     85     int layerSave = layer;
     86     int ansLeft = n-1 + m-1 - layer;
     87     while(ansLeft--){
     88         for(X = 0; X < n; X++){
     89             if(layer-X >= 0 && layer-X < m){
     90                 Y= layer - X;
     91                 if(unlock[X][Y] == true){ // 找到下一层可以走的符号
     92                     if(X+1 <= n-1) ans[layer+1] = ans[layer+1] < maze[X+1][Y] ? ans[layer+1] : maze[X+1][Y];
     93                     if(Y+1 <= m-1) ans[layer+1] = ans[layer+1] < maze[X][Y+1] ? ans[layer+1] : maze[X][Y+1];
     94                 }
     95             }
     96         }
     97         for(X = 0; X < n; X++){
     98             if(layer-X >= 0 && layer-X < m){
     99                 Y= layer - X;
    100                 if(unlock[X][Y] == true){
    101                     if(maze[X+1][Y] == ans[layer+1] && X+1 <= n-1) unlock[X+1][Y] = true;
    102                     if(maze[X][Y+1] == ans[layer+1] && Y+1 <= m-1) unlock[X][Y+1] = true;
    103                 }
    104             }
    105         }
    106         layer++;
    107     }
    108     if(subflag) for(int i = layerSave + 1; i <= n-1+m-1; i++) printf("%c", ans[i]);
    109     else for(int i = 0; i <= n-1+m-1; i++) printf("%c", ans[i]);
    110     printf("
    ");
    111 }
    112 
    113 int main(){
    114     scanf("%d", &T);
    115     while(T--){
    116         clr(maze, 0);
    117         scanf("%d%d", &n, &m);
    118         for(int i = 0; i < n; i++) scanf("%s", maze[i]);
    119         bfs();
    120         Result();
    121     }
    122     return 0;
    123 }
    124 
    125 /*
    126 10
    127 1 1
    128 1
    129 1 1
    130 0
    131 1 5
    132 00101
    133 5 1
    134 0
    135 0
    136 1
    137 0
    138 1
    139 2 2
    140 11
    141 11
    142 3 3
    143 001
    144 111
    145 101
    146 5 5
    147 11101
    148 00100
    149 01000
    150 01011
    151 11111
    152 */
     
  • 相关阅读:
    C#中跨线程访问控件问题解决方案
    asp.net网站中配置文件的加密
    C#中XML使用总结
    连接加密Access数据库的字符串设置方法
    asp.net中常用的26个优化性能的方法
    C#中Math的使用总结
    关于ASP.NET页面打印技术的总结
    域登录获取用户名字的控制
    Web界面设计基本原则
    域登录获得用户名称
  • 原文地址:https://www.cnblogs.com/miaowTracy/p/4836760.html
Copyright © 2020-2023  润新知