标签:
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