题意是:入口:地图的左上角,出口,地图的右上角,求所经过的路径的二进制数最小
照着题解敲了一遍
思路是:首先 二进制 的 位数 越小 越好,其次 二进制的前缀零越多 表示 值越小
首先 在前缀是0的情况下走到最远(最远的定义是 当前坐标是 i , j 则 在保证 位数越小的情况下 则 还剩下 n-i + m-j 的路要走)
剩下的路 必须 向 右走 或者向 下 走,然后 在 其中 选取 0 尽量 多的 路
代码:非原创!!!(from 多校题解)
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> using namespace std; const int MAXN = 1000+10; bool vis[MAXN][MAXN]; char graph[MAXN][MAXN]; int n,m; int dr[] = {0,0,1,-1}; int dc[] = {1,-1,0,0}; struct Node{ int x,y; }; void bfs(){ memset(vis,0,sizeof(vis)); vis[1][1] = 1; queue<Node>q; Node tmp; tmp.x = 1,tmp.y = 1; q.push(tmp); int mx = 2; while(!q.empty()){ tmp = q.front(); q.pop(); if(graph[tmp.x][tmp.y] > ‘0‘){ continue; } for(int i = 0;i < 4;i++){ int xx = tmp.x + dr[i]; int yy = tmp.y + dc[i]; if(xx<1||yy<1||xx>n||yy>m || vis[xx][yy]){ continue; } // cout << "x = " << tmp.x << " y = " << tmp.y << endl; Node tt; tt.x = xx; tt.y = yy; vis[xx][yy] = 1; mx = max(mx,xx+yy); // cout << "x = " << xx << " y = " << yy << endl << endl;; q.push(tt); } } if(vis[n][m] && graph[n][m] == ‘0‘){ printf("0\n"); return; } printf("1"); for(int i = mx;i < m+n;i++){ char mi = ‘1‘; for(int j = 1;j <= n;j++){ if(i-j > 0 && i-j <= m && vis[j][i-j]){ mi = min(mi,graph[j+1][i-j]); //向右走 mi = min(mi,graph[j][i-j+1]);//向下走 } } printf("%c",mi); for(int j = 1;j <= n;j++){ if(i-j > 0 && i-j <= m && vis[j][i-j]){ if(mi == graph[j+1][i-j]){ vis[j+1][i-j] = 1; } if(mi == graph[j][i-j+1]){ vis[j][i-j+1] = 1; } } } } printf("\n"); } int main(){ // freopen("input.txt","r",stdin); int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++){ scanf("%s",graph[i]+1); } for(int i = 0;i <= n+1;i++){ graph[i][0] = ‘2‘; graph[i][m+1] = ‘2‘; } for(int i = 0;i < m+1;i++){ graph[0][i] = ‘2‘; graph[n+1][i] = ‘2‘; } bfs(); } return 0; }
时间: 2024-09-28 19:43:51