您的位置:首页 > 其它

HDU 5335(2015 ACM多校训练第四场1009)

2015-08-01 16:12 465 查看


Walk Out

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 2469 Accepted Submission(s): 485



Problem Description

In an n∗m maze,
the right-bottom corner is the exit (position (n,m) is
the exit). In every position of this maze, there is either a 0 or
a 1 written
on it.

An explorer gets lost in this grid. His position now is (1,1),
and he wants to go to the exit. Since to arrive at the exit is easy for him, he wants to do something more difficult. At first, he'll write down the number on position (1,1).
Every time, he could make a move to one adjacent position (two positions are adjacent if and only if they share an edge). While walking, he will write down the number on the position he's on to the end of his number. When finished, he will get a binary number.
Please determine the minimum value of this number in binary system.



Input

The first line of the input is a single integer T (T=10),
indicating the number of testcases.

For each testcase, the first line contains two integers n and m (1≤n,m≤1000).
The i-th
line of the next n lines
contains one 01 string of length m,
which representsi-th
row of the maze.



Output

For each testcase, print the answer in binary system. Please eliminate all the preceding 0 unless
the answer itself is 0 (in
this case, print 0 instead).



Sample Input

2
2 2
11
11
3 3
001
111
101




Sample Output

111
101




Author

XJZX



题意:
给一个n*m的图。图上每个位置为0或者1。
有一个人在该图中走。每走一个位置把该位置的数字记录下来。
问从这个人从图的左上角(0,0)走到图的右下角(n-1,m-1)形成的二进制数最小是多少,输出这个二进制(该二进制的前导0不必输出)。

思路:
初次看本题时以为是一个从左上角向右下角的dp,但是仔细想想就会有问题,dp的状态转移情况不一定是向右或者是向下的。
例如:

5 5
01111
01000
01010
01010
00011

答案是:1

后来想想应该是一个向下或向右的贪心。但是这样还是无法处理上述的情况,最后只能对这种情况进行特殊处理;
当起始点为0时先把所有与起始点相邻的0点跑出来,放进优先队列里面,然后取其中横坐标+纵坐标最大的值(横坐标+纵坐标越大,离(n-1,m-1)的距离越近,二进制位数越小,二进制值越小),当然如果这样的值有多个则都取出来,每个都进行向下向右的BFS广搜,而且广搜的同时,再与终点距离相同的点中,优先选择所有的0点,一旦存在0点则放弃所有1点。

至于这些如何实现。。。。。。。。。。。。。。不得不承认自己还是太弱了。竟然需要用两个优先队列,两个普通队列来实现。
后来看了别人短小精悍的代码后更是感觉自己的代码无法直视O__O "…
虽然这样写起来思路非常清晰,但是代码还是太冗长了 (>﹏<)

#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

const int maxx = 1000 + 10;
int n, m;
char str[maxx][maxx];
char ans[maxx*maxx];
char ans_str[maxx*maxx];
bool vis[maxx][maxx];
int kjudge;

int dir1[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
struct node1{
    int x;
    int y;
    bool operator < (const node1 & a)const{
        return a.x+a.y > x+y;
    }
};
priority_queue<node1> pp1;
queue<node1> p1;

int dir2[2][2] = {{1,0},{0,1}};
struct node2{
    int x;
    int y;
    int num;
    int id;
    bool operator < (const node2& a) const {
        if(a.num == num) return a.id < id;
        return a.num < num;
    }
};
priority_queue<node2> pp2;
queue<node2> p2;

bool ok(int x,int y){
    if(x<0||x>=n)
        return false;
    if(y<0||y>=m)
        return false;
    return true;
}

bool ok1(int x,int y){
    if(ok(x,y)&&str[x][y] == '0'){
        return true;
    }
    return false;
}

bool ok2(int x,int y){
    if(ok(x,y)&&vis[x][y] == false){
        return true;
    }
    return false;
}

void output(int len){
    int i = 0;
    if(ans_str[0] == '9') i++;
    for(; i < len; ++i){
        printf("%c",ans_str[i]);
    }
    printf("\n");
}

int bfs2(int x,int y){
    node2 k;
    if(str[n-1][m-1] == '9'){
        printf("0\n");
        return -1;
    }
    if(x == n-1 &&y == m-1){
        printf("%c\n",str[n-1][m-1]);
        return -1;
    }
    memset(vis,false,sizeof(vis));
    memset(ans,'_',sizeof(ans));
    k.x = x;
    k.y = y;
    k.num = 1;
    ans[0] = str[k.x][k.y];
    k.id = str[k.x][k.y] - '0';
    vis[x][y] = true;
    pp2.push(k);
    int now = k.num;
    int judge = k.id;
    while(!pp2.empty()){
        node2 q = pp2.top();
        pp2.pop();
        if(now != q.num){
            now = q.num;
            judge = q.id;
        }
        if(judge == q.id){
            for(int i = 0;i < 2; ++i){
                int dx = dir2[i][0]+q.x;
                int dy = dir2[i][1]+q.y;
                if(dx == n-1 && dy == m-1){
                    ans[q.num] = str[dx][dy];
                    if(!kjudge){
                        for(int j = 0;j <= q.num; ++j){
                            ans_str[j] = ans[j];
                        }
                    }else{
                        int mj = 0;
                        for(int j = 0;j <= q.num; ++j){
                            if(ans_str[j] > ans[j]){
                                mj = 1;
                                break;
                            }
                        }
                        if(mj){
                            for(int j = 0;j <= q.num; ++j){
                                ans_str[j] = ans[j];
                            }
                        }
                    }
                    while(!pp2.empty()) pp2.pop();
                    return q.num+1;
                }
                if(ok2(dx,dy)){
                    if(ans[q.num] == '_')ans[q.num] = str[dx][dy];
                    else ans[q.num] = min(ans[q.num],str[dx][dy]);
                    vis[dx][dy] = true;
                    node2 temp;
                    temp.id = str[dx][dy] - '0';
                    temp.x = dx;
                    temp.y = dy;
                    temp.num = q.num+1;
                    pp2.push(temp);
                }
            }
        }
    }
}

void bfs1(){ ///找起点位置
    node1 k;
    k.x = 0;
    k.y = 0;
    kjudge = 0;
    int klen = -1;
    if(str[0][0] == '0') {
        p1.push(k);
        str[0][0] = '9';
        while(!p1.empty()){
            node1 q = p1.front();
            pp1.push(q);
            p1.pop();
            for(int i = 0;i < 4; ++i){
                int dx = dir1[i][0] + q.x;
                int dy = dir1[i][1] + q.y;
                if(ok1(dx,dy)){
                    node1 temp;
                    temp.x = dx;
                    temp.y = dy;
                    str[dx][dy] = '9';
                    p1.push(temp);
                }
            }
        }
        int judge  = pp1.top().x + pp1.top().y;
        while(!pp1.empty()){
            node1 temp = pp1.top();
            if(judge == temp.x+temp.y){
                klen = bfs2(temp.x,temp.y);
            }
            pp1.pop();
        }
    }else{
        klen = bfs2(0,0);
    }
    if(klen != -1)output(klen);
}

int main(){
    int T;
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i = 0;i < n; ++i){
            scanf("%s",str[i]);
        }
        bfs1();
    }
    return 0;
}


如有BUG,请大家务必指出,不胜感激~

联系方式:274489985@qq.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: