HDU 5335 BFS

来源:互联网 发布:网络博物馆 编辑:程序博客网 时间:2024/06/04 20:11

点击打开链接

题意:从左上角走到右下角的路径中要求所有数字组成的二进制最小

思路:考虑如果第一个元素不是1的话,该怎么办,因为要求前缀0不输出,那么我们找到所有的0可以走到的1,然后在处理,因为要这个二进制数最小,所以它的长度越短越好,那么对于所有0到达的第一个1,我们找到与终点的最近距离,然后将满足的全部放进容器中,如果第一个是1的话,也一样进去的只能是第一个元素,然后现在的元素到终点的距离相等,也就是说它们组成的数长度相同,那么怎么让它变小呢,就是如果当前步数可以走到0点,那么所有走到1点的全部不要了,这样走到最后的就是最小的了,具体看代码好理解些

#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=1010;int n,m,num[maxn][2],dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}},ans[maxn];bool vis[maxn][maxn],vis1[maxn][maxn];char str[maxn][maxn];struct pos{    int x,y;    pos(int a,int b){x=a;y=b;}};vector<pos>G;vector<pos>G1;vector<pos>G2;struct edge{    int x,y;};void bfs(){    queue<edge>que;    edge c,ne;    for(int i=0;i<n;i++)        for(int j=0;j<m;j++)            vis[i][j]=0;    c.x=0,c.y=0;    vis[c.x][c.y]=1;    que.push(c);    while(!que.empty()){        c=que.front();que.pop();        for(int i=0;i<4;i++){            int xx=c.x+dir[i][0];            int yy=c.y+dir[i][1];            if(xx<0||xx>n-1||yy<0||yy>m-1||vis[xx][yy]) continue;            if(str[xx][yy]=='1'){                vis[xx][yy]=1;continue;            }            vis[xx][yy]=1;            ne.x=xx;ne.y=yy;            que.push(ne);        }    }}void rbfs(int len){    int k=1;ans[0]=1;    while(k<=len){        G1.clear();G2.clear();        int lll=G.size();        for(int i=0;i<lll;i++){            pos pp=G[i];            for(int j=0;j<2;j++){                int xx=pp.x+dir[j][0];                int yy=pp.y+dir[j][1];                if(xx<0||xx>n-1||yy<0||yy>m-1||vis1[xx][yy]) continue;                if(str[xx][yy]=='0') G1.push_back(pos(xx,yy));                else if(str[xx][yy]=='1') G2.push_back(pos(xx,yy));                vis1[xx][yy]=1;            }        }        if(G1.size()!=0) G=G1,ans[k++]=0;        else G=G2,ans[k++]=1;    }}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);G.clear();G1.clear();G2.clear();        memset(vis1,0,sizeof(vis1));        for(int i=0;i<n;i++) scanf("%s",str[i]);        int k=0,min1=inf;        if(str[0][0]=='1'){            num[0][0]=0;num[0][1]=0;k=1;min1=n+m-2;        }        else{            bfs();            if(vis[n-1][m-1]){                if(str[n-1][m-1]=='1') printf("1\n");                else printf("0\n");                continue;            }            for(int i=0;i<n;i++){                for(int j=0;j<m;j++){                    if(vis[i][j]&&str[i][j]=='1'){                        num[k][0]=i,num[k++][1]=j;                        min1=min(min1,(n-i-1)+(m-j-1));                    }                }            }        }        for(int i=0;i<k;i++){            int t=n-num[i][0]+(m-num[i][1])-2;            if(t==min1) G.push_back(pos(num[i][0],num[i][1]));        }        rbfs(min1);        for(int i=0;i<=min1;i++) printf("%d",ans[i]);        printf("\n");    }    return 0;}

0 0
原创粉丝点击