标签:搜索
题意是给你一个n*m的有0 1组成的矩阵 起点为坐上角 终点为右下角 从起点走到终点组成的一个二进制数最小;
思路:
1. 如果起点为零 则找到与起点相邻的联通0 的点 找到距离终点最近的一些点 然后找到最小的二进制数(建议用 bfs)
2.起点不为0 则直接从起点开始找最小的二进制数 具体找法为:
把下一步的点走找出来 如果其中有0的点 则不用走位1的点 把为零的加入队列 如果没有 则把所有的都加入队列 走的时候只用走右边和下边 想想为什么(2^ n肯定大于 2^(n-1)+.....2^0 说明长度越短越小)注意走过的点不能再走了(RE了好久) 具体实现我是用了一个优先队列(找到距离最小且为0 的起点) 一个普通队列 在跑起点时候 和对每个起点找到最小路径的时候。。。。。
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> using namespace std; char map[2100][2100]; int dir[4][2]={0,1,0,-1,1,0,-1,0}; int mark[2010][2010]; int n,m; int path[3100]; struct node { int x,y; }a,b; struct Node { int x,y,dis; bool operator < (const Node& g) const { return dis>g.dis; } }a1,b1; priority_queue<Node>Q; int bfs1(int x,int y)//找到所有起点 { int flash=0; a.x=x; a.y=y; a1.x=x; a1.y=y; a1.dis=n-x+m-y-1; Q.push(a1); queue<node>q; memset(mark,0,sizeof(mark)); if(map[a.x][a.y]==‘0‘) q.push(a); mark[a.x][a.y]=1; while(!q.empty()) { b=q.front(); q.pop(); for(int i=0;i<4;i++) { a.x=b.x+dir[i][0]; a.y=b.y+dir[i][1]; if(a.x<0||a.x>=n||a.y<0||a.y>=m) continue; if(mark[a.x][a.y]==0&&map[a.x][a.y]==‘0‘) { mark[a.x][a.y]=1; q.push(a); if(a.x==n-1&&a.y==m-1) flash=1; a1.x=a.x; a1.y=a.y; a1.dis=n+m-a.x-a.y-1; Q.push(a1); } } } if(flash) return 1; return 0; } int bfs2(int x,int y,int dis)//对每个起点 找到最小路径 { int route[3100]; int leap[3100][3]; memset(mark,0,sizeof(mark));//开始少了这个标记走过的 re了好久 queue<node>qq; a.x=x; a.y=y; qq.push(a); int flash,j=0; route[++j]=map[a.x][a.y]-‘0‘; int k; while(1)//对每层的情况 { k=0; flash=0; while(!qq.empty()) { b=qq.front(); qq.pop(); if(b.x+1<n&&mark[b.x+1][b.y]==0) { mark[b.x+1][b.y]=1; leap[++k][1]=b.x+1; leap[k][2]=b.y; if(map[b.x+1][b.y]==‘0‘) flash=1; } if(b.y+1<m&&mark[b.x][b.y+1]==0) { mark[b.x][b.y+1]=1; leap[++k][1]=b.x; leap[k][2]=b.y+1; if(map[b.x][b.y+1]==‘0‘) flash=1; } } if(k==0) break; if(flash) route[++j]=0; else route[++j]=1; for(int i=1;i<=k;i++) { a.x=leap[i][1]; a.y=leap[i][2]; if(flash==0) { qq.push(a); } else { if(map[a.x][a.y]==‘0‘) qq.push(a); } } } flash=0; for(int i=1;i<=j;i++) { if(flash) path[i]=route[i]; else { if(route[i]<path[i]) { path[i]=route[i]; flash=1; } } } return 0; } int main() { int T,i,j; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) scanf("%s",map[i]); if(n==1&&m==1) {printf("%c\n",map[0][0]);continue;} while(!Q.empty()) { a1=Q.top(); Q.pop(); } int d=bfs1(0,0); if(d==1) {printf("0\n");continue;} for(i=0;i<=2010;i++) path[i]=1; b1=Q.top(); Q.pop(); int Min=b1.dis; bfs2(b1.x,b1.y,b1.dis); while(!Q.empty()) { b1=Q.top(); Q.pop(); if(b1.dis>Min) break; bfs2(b1.x,b1.y,b1.dis); } if(path[1]==0) i=2; else i=1; for(;i<=Min;i++) printf("%d",path[i]); printf("\n"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:搜索
原文地址:http://blog.csdn.net/zxf654073270/article/details/47277045