HDU 5335 Walk Out

来源:互联网 发布:淘宝远航数码是黑店 编辑:程序博客网 时间:2024/06/16 00:55


多校训练第四场

这是一个搜索的题目要用一次深搜找到初始位置,再用宽搜找到答案,首先分析一下题目发现,从起点来向周围的点搜索,如果发现0则优先进入零,但是不进入1,如果没有0则都需要搜索一遍,不过我们再仔细分析题目就会发现,一旦第一个一进入则只可能向右或者下搜索,因为一旦有一出现那么向上或者向左搜索只会使数位更大,这是比踩1更可怕的事情,而对于一个点(x,y)来说最小的数位就是n- x + m - y如果比这个大的话就绝对不是最优解;由此我们发现我们首先要找到一个最佳的初始位位置,也就是数位最小而且可以通过一串0到达的位置,这个位置首先要用款搜找到,需要注意的是这个位置可能不止一个。好了找到最佳的初始位置之后我们需要做的就是搜索最佳路径,上面的分析告诉我们我们只可能向下和向右搜索,而且优先走0,遇到0绝对不走1,如果下一步全是1,那就都要搜索,于是这样就保证了搜索过的点走过的路径值是一样的而且是最优的,这样就不用一次一次的回去找路径再判断,因为搜索的每一个点都是最优的,再找到下一步中最优的存为要搜索的位置,当然如果那个位置在里面那就不用搜索了,这个栈是我用一个数组手写的,最后再用一个char 数组记录下路径,思路就是这样。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <functional>#include <cstdio>#include <queue>#include <map>#include <algorithm>#include <stack>#include <utility>typedef long long ll;using namespace std;const int mx = 1009;bool used[mx][mx];int s[mx][mx],n,m,sum;char str[mx << 1],cccc[mx];int nod[mx << 1][2],num,cnt;void bfs(){    int i,j,k,x,y,OK,a,b,all;    while(sum < (m + n - 2))    {        OK = 1;        for(i = 0; i < num && OK; i++)        {            k = nod[i][sum&1];            x = k / m;            y = k % m;            if(y + 1 < m &&s[x][y + 1] == 0)                OK = 0;            if(x + 1 < n &&s[x + 1][y] == 0)                OK = 0;//                printf(" k = %d x = %d y = %d OK = %d\n",k,x,y,OK);        }        if(OK)            str[cnt++] = '1';        else            str[cnt++] = '0';        all = num;        num = 0;        a = sum & 1;        b = (sum + 1) & 1;        for(i = 0; i < all; i++)        {            k = nod[i][a];            x = k / m;            y = k % m;            if(x + 1 < n && !used[x + 1][y] && s[x + 1][y] == OK)                used[x + 1][y] = true,nod[num++][b] = k + m;            if(y + 1 < m && !used[x][y + 1] && s[x][y + 1] == OK)                used[x][y + 1] = true,nod[num++][b] = k + 1;        }        sum++;    }}void dfs(int a,int b){//    printf("a = %d b = %d\n",a,b);    used[a][b] = true;    if(s[a][b] == 1)    {        if(a + b == sum)            nod[num++][sum&1] = a * m + b;        if(a + b > sum)        {            sum = a + b;            num = 0;            nod[num++][sum&1] = a * m + b;        }        return;    }    if(a + b == n + m - 2)    {        sum = n + m - 2;        return;    }    if(a + 1 < n &&!used[a + 1][b]) dfs(a + 1,b);    if(b + 1 < m &&!used[a][b + 1]) dfs(a,b + 1);    if(a > 0 && !used[a - 1][b]) dfs(a - 1,b);    if(b > 0 && !used[a][b - 1]) dfs(a,b - 1);}int main (){    int T,i,j,k;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        for(i = 0; i < n ; i++)        {            scanf("%s",cccc);            for(j = 0; j < m; j++)                s[i][j] = cccc[j] - '0';        }//        printf("awsdfasdf\n");        memset(used,false,sizeof(used));        sum = 0;        dfs(0,0);        if(sum == n + m - 2)        {            printf("%d\n",s[n - 1][m - 1]);            continue;        }        memset(used,false,sizeof(used));        cnt = 0;        str[cnt++] = '1';        bfs();        for(i = 0; i < cnt; i++)            printf("%c",str[i]);        printf("\n");    }}

0 0