您的位置:首页 > 其它

hdu 5335 Walk Out

2015-08-01 23:05 323 查看
官方解析:

If we require that the explorer could only move downward or rightward, this problem will be easier: the length of the binary number will always be n+m-1, and
we could work this out length by length. At first, the length of the binary number is 1 (at the entrance). If the entrance is adjacent to some 0, the explorer would definitely go to these 0s; otherwise, he could only go to 1s. In either occasion, there will
be several possible positions, but the binary numbers will always be same. After getting the minimum value and the possible positions of this length, we could walk the next step, by finding the adjacent 0s with this length's possible position. Finally, we
could arrive at the exit.

Now return to the original problem: the explorer could move in any direction. However, is moving for long optimal? Absolutely not. A longer binary number is always larger than a short one, but do not forget the preceding 0s. In fact. The explorer could walk
on any number of 0s at first, and still keep the binary number equal to 0. Therefore, we need to find all the positions that are connected by 0s with the entrance. The explorer would walk on these positions freely, and then step on the first 1. He should make
the first 1 nearest to the exit. After that, we could use the solution in the first paragraph to solve the whole problem.

相应的解法:

#include <iostream>  
#include <queue>  
#include <cstdio>  
#include <cstring>  
using namespace std;  
const int inf = 0x3f3f3f3f;  
int mark[1010][1010], n, m, cnt; // cnt 表示可行点的个数;  
char s[1010][1010];  
struct node{  
    int x, y;  
}_n[2010];  
void init(){  
    scanf("%d%d", &n, &m);  
    for(int i = 0; i < n; ++i){  
        scanf("%s", s[i]);  
    }  
}  
int dir[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};  
void find_start(){  
    memset(mark, -1, sizeof(mark));  
    if(s[0][0] == '1'){  
        cnt = 1;  
        _n[0].x = 0;  
        _n[0].y = 0;  
        return ;  
    }  
    queue<node> q;  
    node cur, next;  
    cur.x = 0, cur.y = 0;  
    q.push(cur);  
    while(!q.empty()){  
        cur = q.front();  
        q.pop();  
        for(int i = 0; i < 4; ++i){  
            next.x = cur.x + dir[i][0];  
            next.y = cur.y + dir[i][1];  
            if(next.x < 0 || next.y < 0 || next.x >= n || next.y >= m)  
                continue;  
            if(mark[next.x][next.y] != -1)  
                continue;  
            if(s[next.x][next.y] == '1')  
                mark[next.x][next.y] = 1;  
            if(s[next.x][next.y] == '0'){  
                mark[next.x][next.y] = 0;  
                q.push(next);  
            }  
        }  
    }  
    if(mark[n - 1][m - 1] == 0){  
        cnt = 0;  
        return ;  
    }  
    cnt = 0;  
    int key = inf;  
    for(int i = 0; i < n; ++i){  
        for(int j = 0; j < m; ++j){  
            if(mark[i][j] == 1){  
                int x = n + m - i - j - 2; // 走到(n-1, m-1);  
                if(x < key){  
                    cnt = 0;  
                    _n[cnt].x = i;  
                    _n[cnt++].y = j;  
                }  
                if(x == key){  
                    _n[cnt].x = i;  
                    _n[cnt++].y = j;  
                }  
            }  
        }  
    }  
}  
void bfs(){  
    queue<node> q1, q2;  
    node cur, next;  
    memset(mark, 0, sizeof(mark));  
    for(int i = 0; i < cnt; ++i){  
        mark[_n[i].x][_n[i].y] = 1;  
        q1.push(_n[i]);  
    }  
    printf("1");  
    if(mark[n - 1][m - 1] == 1)  
        return ;  
    while(1){  
        int flag = 1;   // 找到0(flag = 0) 没找到flag = 1;  
        while(!q1.empty()){  
            cur = q1.front();  
            q1.pop();  
            for(int i = 0; i < 2; ++i){  
                next.x = cur.x + dir[i][0];  
                next.y = cur.y + dir[i][1];  
                if(next.x < 0 || next.x >= n || next.y < 0 || next.y >= m)  
                    continue;  
                if(!mark[next.x][next.y]){  
                    mark[next.x][next.y] = 1;  
                    if(s[next.x][next.y] == '0')  
                        flag = 0;  
                    q2.push(next);  
                }  
            }  
        }  
        printf("%d", flag);  
        if(mark[n - 1][m - 1] == 1)  
            break;  
        while(!q2.empty()){  
            cur = q2.front();  
            q2.pop();  
            if(flag == 0){  
                if(s[cur.x][cur.y] == '0')  
                    q1.push(cur);  
            }  
            else  
                q1.push(cur);  
        }  
    }  
}  
int main()  
{  
    int T;  
    cin >> T;  
    while(T--){  
        init();  
        find_start();  
        if(cnt == 0)  
            printf("0\n");  
        else{  
            bfs();  
            printf("\n");  
        }  
    }  
    return 0;  
}


我的AC代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
struct node
{
    int x, y;
};
char a[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2] = {1,0, 0,1, -1,0, 0,-1};
int x, y, n, m;
bool check (int x, int y)
{
    if (x<0 || y<0 || x>=n || y>=m)
        return false;
    return true;
}
void bfs ()
{
    node p, q;
    p.x = x, p.y = y;
    queue <node> Q;
    Q.push (p);
    while (!Q.empty())
    {
        p = Q.front();
        Q.pop();
        for (int i=0; i<4; i++)
        {
            q.x = p.x + dir[i][0];
            q.y = p.y + dir[i][1];
            if (check(q.x, q.y) && !vis[q.x][q.y])
            {
                vis[q.x][q.y] = true;
                if (a[q.x][q.y] == '0')
                    Q.push (q);
                if (x + y < q.x + q.y)
                    x = q.x, y = q.y;
            }
        }
    }
}
int main ()
{
    int t;
    scanf ("%d", &t);
    while (t --)
    {
        memset (vis, false, sizeof(vis));
        vis[0][0] = true;
        scanf ("%d %d", &n, &m);
        for (int i=0; i<n; i++)
            scanf ("%s", a[i]);
        x = y = 0;
        if (a[x][y] == '0')
            bfs ();
        if (a[x][y] == '0')
            putchar('0');
        else
        {
            bool nowflag = false;
            putchar ('1');
            for (int i=x+y; i<n+m-2; i++)
            {
                bool flag = false;
                for (x=0; x<=i; x++)
                {
                    y = i - x;
                    if (!check(x, y) || !vis[x][y])
                        continue;
                    if (nowflag && a[x][y]=='1')
                        continue;
                    for (int j=0; j<2; j++)
                    {
                        int xx = x + dir[j][0];
                        int yy = y + dir[j][1];
                        if (!check(xx,yy))
                            continue;
                        vis[xx][yy] = true;
                        if (a[xx][yy] == '0')
                            flag = true;
                     }
                }
                nowflag = flag;
                putchar (flag?'0':'1');
            }
        }
        puts("");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: