标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5335
2 2 2 11 11 3 3 001 111 101
111 101
/** hdu5335 多校联合第四场1009 搜索 题目大意:给定一个由0和1组成的棋盘,从左上角走到右下角路径(上下左右四种行走方式)组成二进制数问最小的是什么 解题思路:(转)如果我们规定这个人只能向下走或者向右走的话,问题会变的简单,二进制长度为n-m+1,然后我们可以一步一步求它每一步走的情况。 首先他的二进制第一位一定要为0。在第一位为0之后一定只会向下或者向右走到终点,因为中间如果向上走或者向左走的话,二进制的 位数会增加,大小肯定增大,所以问题的关键是找出从原点一直走0的位置,中间经过的0的位置距离终点最短的点,在这之后便只能向 下走或者向右走。 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> using namespace std; const int maxn=1003; int n,m,ans; bool flag[maxn][maxn]; char a[maxn][maxn]; int dx[][2]= {1,0,0,1,-1,0,0,-1}; void bfs() { queue <pair<int,int> >q; memset(flag,0,sizeof(flag)); q.push(make_pair(0,0)); while(!q.empty()) { int x=q.front().first; int y=q.front().second; q.pop(); for(int i=0; i<4; i++) { int xx=x+dx[i][0]; int yy=y+dx[i][1]; if(flag[xx][yy]||xx<0||xx>=n||yy<0||yy>=m)continue; flag[xx][yy]=1; ans=max(xx+yy,ans); if(a[xx][yy]=='0') q.push(make_pair(xx,yy)); } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) { scanf("%s",a[i]); } ans=0; flag[0][0]=1; if(a[0][0]=='0')bfs(); if(ans==n+m-2) { printf("%c\n",a[n-1][m-1]); continue; } printf("1"); bool ok=0; for(int i=ans; i<n-1+m-1; i++) { bool judge=0; for(int k=0; k<=i; k++) { int x=k; int y=i-k; if(x<0||x>=n||y<0||y>=m||flag[x][y]==0)continue; if(ok&&a[x][y]=='1')continue; for(int j=0; j<2; j++) { int xx=x+dx[j][0]; int yy=y+dx[j][1]; if(xx<0||xx>=n||yy<0||yy>=m)continue; flag[xx][yy]=1; if(a[xx][yy]=='0')judge=1; } } ok=judge; if(judge)printf("0"); else printf("1"); } printf("\n"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/47169487