2 2 2 11 11 3 3 001 111 101
111 101
题意:
给你一个迷宫,迷宫由0 1串组成,让你从 1 1 点走到 n,m点 ,路径上的所以点连起来就是个二进制数,求这个二进制数的最小值
思路:
一个二进制数想要小,首先位数一定要小,其次每一位让0尽肯能的出现在前面,也会小,所以第一步找到距离终点最近的一个1,这个1满足起点到这个1直接只由0组成
找到这个1之后就可以贪心走又下方(不向左上的原因是会使位数变大),这里需要用生命来优化,走过的点不能走,不能让地图每个点都要个string 来标记这个点的值,这样都会爆内存。标记用一个string 来记录当前结果,用另一个变量标记这个数是搜索的第几层,总之用生命来优化,下面贴代码
/********************************* ** 2015 Multi-University Training Contest 4 1009 ** 2015-7-31 ** by calamity_coming ** hdu 5335 **********************************/ #include <bits/stdc++.h> using namespace std; const int inf=0x7f7f7f7f; typedef unsigned int intt; typedef long long ll; const int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; char maze[1010][1010]; int n,m; struct Point { int x,y; int fair()//到终点的距离 { return m + n - x - y - 2; } Point (int _x = 0,int _y = 0) : x(_x) , y(_y) {} }; class Solution { bool end_zero; queue<Point> jb; int min_long; string final_ans; public: Solution() : end_zero (false) , final_ans("1") { cin>>n>>m; for(int i=0; i<n; ++i) { cin>>maze[i]; } if(maze[n-1][m-1] == '0')//让他为0好判断 { end_zero = true; maze[n-1][m-1] = '1'; } min_long = n+m-2; } /********************************************************* ** 寻找第一个1出现的位置 ** 前提,已经把结尾强制设为1 ************************************************************/ void find_one() { if(maze[0][0] == '1') { jb.push(Point(0,0)); return; } queue<Point> ac; ac.push(Point(0,0)); while(!ac.empty()) { Point adc = ac.front(); ac.pop(); for(int i=0; i<4; ++i) { int x = dir[i][0] + adc.x; int y = dir[i][1] + adc.y; if(x<0 || x>=n || y<0 || y>=m) continue; if(maze[x][y] == '0') { ac.push(Point(x,y)); maze[x][y] = '#'; continue; } if(maze[x][y] == '1') { Point ap(x,y); jb.push(ap); maze[x][y] = '*'; if(ap.fair() < min_long) { min_long = ap.fair(); update_queue();//一定不为空 } } } } } void update_queue()//更新队列值,始终是满足最小的(用时间换空间) { for(int i=0,len = jb.size(); i<len; ++i) { Point adc = jb.front(); jb.pop(); if(min_long == adc.fair()) { jb.push(adc); } } } /********************************************************** ** 广搜找到结果,只往右下方走 ** 用生命在标记,防止爆内存 ** 把走过的0变成#,1变成*,可以防止重复走 *************************************************************/ void bfs() { while(!jb.empty()) { Point adc = jb.front(); jb.pop(); if(min_long == 0) { return ; } if(min_long == adc.fair() && maze[adc.x][adc.y] == '*' && final_ans[final_ans.size()-1] == '0') //被抛弃的点 { continue; } if(adc.y + 1 < m)//向右 { if(maze[adc.x][adc.y+1] == '0') { Point ap = adc; ap.y++; if(min_long == ap.fair() + 1)//1 -> 10 { min_long = ap.fair(); final_ans += '0'; } else if(final_ans[final_ans.size()-1] == '1')//11 -> 10 { final_ans[final_ans.size()-1] = '0'; } jb.push(ap); maze[adc.x][adc.y+1] = '#'; } else if(maze[adc.x][adc.y + 1] == '1') { if(adc.x + 1 >= n || (maze[adc.x+1][adc.y] != '0') && maze[adc.x+1][adc.y] != '#') { Point ap = adc; ap.y++; if(min_long == ap.fair() + 1)//111 -> 1111 { min_long --; final_ans += '1'; jb.push(ap); maze[adc.x][adc.y+1] = '*'; } else if(final_ans[final_ans.size()-1] == '1')// 11-> 11 { jb.push(ap); maze[adc.x][adc.y+1] = '*'; } } } } if(adc.x + 1 < n)//向下 { if(maze[adc.x+1][adc.y] == '0') { Point ap = adc; ap.x++; if(min_long == ap.fair() + 1)//111 -> 1110 { min_long = ap.fair(); final_ans += '0'; } else if(final_ans[final_ans.size()-1] == '1')//1111 -> 1110 { final_ans[final_ans.size()-1] = '0'; } jb.push(ap); maze[adc.x+1][adc.y] = '#'; } else if(maze[adc.x+1][adc.y] == '1') { if(adc.y + 1 >= m || (maze[adc.x][adc.y+1] != '0' && maze[adc.x][adc.y+1] != '#')) { Point ap = adc; ap.x++; if(min_long == ap.fair() +1)//111 -> 1111 { min_long = ap.fair(); final_ans += '1'; jb.push(ap); maze[adc.x+1][adc.y] = '*'; } else if(final_ans[final_ans.size()-1] == '1')// 1111 -> 1111 { jb.push(ap); maze[adc.x+1][adc.y] = '*'; } } } } } } void Win_S5() { find_one(); update_queue();//最后一定要再次更新一下,删除不该有的东西 bfs(); if(end_zero) { final_ans[final_ans.size()-1] = '0'; } cout<<final_ans<<endl; } }; int main() { ios::sync_with_stdio(false); int t; int cot = 0; cin>>t; while(t--) { Solution OMG; OMG.Win_S5(); } return 0; }
挺虐心的,200多行,WA了一天,最后发现是队列少更新一次,还是不够细心啊
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/calamity_coming/article/details/47170467