求从0,0点到n-1,m-1点的最小二进制数
分两种情况:
1:若0,0点为‘1’,则为起点,进bfs贪心
2:若0,0点为‘0’,则找出起点所连接的所有‘0’点所能接触到的‘1’点,取其中离终点曼哈顿距离最小的点当做起点,保证01串最短
bfs贪心:每次只往右或下方走,对所有能到达的新点,若有0,则只进是0的点,否则进1
#include "stdio.h" #include "string.h" #include "queue" using namespace std; const int inf=0x3f3f3f3f; const int dir[4][2]={ {1,0},{0,1},{0,-1},{-1,0} }; struct node { int x,y; }s[2010]; char str[1010][1010]; int n,m,cnt; int mark[1010][1010]; void find_s() { queue<node>q; node cur,next; int i,j,x,key; memset(mark,-1,sizeof(mark)); if (str[0][0]=='1') // 若0,0点为‘1’,则起点唯一 { cnt=1; s[0].x=0; s[0].y=0; return ; } cur.x=0;cur.y=0; q.push(cur); mark[0][0]=0; while (!q.empty()) { cur=q.front(); q.pop(); for (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 (str[next.x][next.y]=='1') mark[next.x][next.y]=1; if (str[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; key=inf; // 找出离终点曼哈顿距离最小的且可由起点‘0’到达的‘1’点 for (i=0;i<n;i++) for (j=0;j<m;j++) if (mark[i][j]==1) { x=n+m-2-i-j; if (x<key) { cnt=0; s[cnt].x=i; s[cnt].y=j; cnt++; key=x; } else if (x==key) { s[cnt].x=i; s[cnt].y=j; cnt++; } } } /* 1 5 6 011101 001111 010111 111110 110101 */ void bfs() { queue<node>q1,q2; node cur,next; int i,flag; memset(mark,0,sizeof(mark)); for (i=0;i<cnt;i++) { mark[s[i].x][s[i].y]=1; q1.push(s[i]); } printf("1"); if (mark[n-1][m-1]==1) return ; while (1) { flag=1; while (!q1.empty()) { cur=q1.front(); q1.pop(); for (i=0;i<2;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]==0) { if (str[next.x][next.y]=='0') flag=0; mark[next.x][next.y]=1; q2.push(next); } } } printf("%d",flag); // 若下一步有‘0’可走,只走0 if (mark[n-1][m-1]==1) break; while (!q2.empty()) { cur=q2.front(); q2.pop(); if (flag==0) { if (str[cur.x][cur.y]=='0') q1.push(cur); } else q1.push(cur); } } } int main() { int t,i; scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); for (i=0;i<n;i++) scanf("%s",str[i]); find_s(); // 找出可行的起点 if(cnt==0 ) //从起点可只通过0直接到达终点 printf("0"); else bfs(); printf("\n"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 10:59:59