poj 3897 Maze Stretching 二分+A*搜索
题意,给你一个l,和一个地图,让你从起点走到终点,使得路程刚好等于l。
你可以选择一个系数,把纵向的地图拉伸或收缩,比如你选择系数0.5,也就是说现在上下走一步消耗0.5的距离,如果选择系数3,也就是说上下一步消耗3的距离。
左右不能改变。
Hint中提示了答案在0--10之间,其实就透露出了二分的思想。
我们对系数P进行二分,对每一个系数P进行一次bfs,如果可以在小于等于l的步数内找到解,则增加下界,否则减小上界。
由于上下和左右的消耗值不相同,所以我们采用A*算法,设估价值为当前点到目标点的哈弗曼距离(注意上下距离要乘上系数P),然后利用优先队列搜索。
我试了几下,精度开到1e-6才不会wa
如果用普通的bfs做,注意不能一遇到终点就结束,有可能丢失掉最优解。
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- #include<cmath>
- #include<iostream>
- using namespace std;
- char map[105][105];
- int CAS;
- double l;
- int n,len;
- int end,st;
- int dx[]={-1,1,0,0};
- int dy[]={0,0,-1,1};
- struct node
- {
- double dis;
- int x;
- int y;
- double h;
- bool operator < (const node &a) const
- {
- return dis+h>a.dis+h;
- }
- }start;
- double geth(int x,int y,double k)
- {
- double h=0;
- int ex=end/len;
- int ey=end%len;
- return abs(ey-y)+abs(ex-x)*k;
- }
- bool isok(int x,int y)
- {
- return x>=0&&x<n&&y>=0&&y<len&&map[x][y]!='#';
- }
- double vis[105][105];
- bool bfs(double k)
- {
- for(int i=0;i<n;i++)
- for(int j=0;j<len;j++)
- vis[i][j]=100000000;
- priority_queue<node> q;
- q.push(start);
- vis[start.x][start.y]=1;
- node tmp,tt;
- while(!q.empty())
- {
- tmp=q.top();q.pop();
- for(int d=0;d<4;d++)
- {
- tt=tmp;
- tt.x=tmp.x+dx[d];
- tt.y=tmp.y+dy[d];
- if(isok(tt.x,tt.y))
- {
- tt.h=geth(tt.x,tt.y,k);
- if(d<=1) tt.dis+=k;
- else tt.dis+=1;
- if(tt.dis<vis[tt.x][tt.y]) vis[tt.x][tt.y]=tt.dis;
- else continue;
- if(tt.x==end/len&&tt.y==end%len)
- {
- if(tt.dis<=l) return true;
- else return false;
- }
- q.push(tt);
- }
- }
- }
- return false;
- }
- int main()
- {
- int cas;
- CAS=1;
- scanf("%d",&cas);
- while(cas--)
- {
- scanf("%lf%d",&l,&n);getchar();
- for(int i=0;i<n;i++)
- gets(map[i]);
- len=strlen(map[0]);
- for(int i=0;i<n;i++)
- for(int j=0;j<len;j++)
- {
- if(map[i][j]=='S')
- {
- st=i*len+j;
- }
- if(map[i][j]=='E')
- {
- end=i*len+j;
- }
- }
- start.dis=0;
- start.x=st/len;
- start.y=st%len;
- double l=0;
- double r=11;
- double mid=(l+r)/2.0;
- while(r-l>1e-6)
- {
- // cout<<l<<' '<<r<<' '<<mid<<endl;
- mid=(l+r)/2.0;
- if(bfs(mid)) l=mid;
- else r=mid;
- }
- printf("Case #%d: %.3f%%\n",CAS++,mid*100);
- }
- return 0;
- }
/*
我是一只奔跑的小菜鸡……
*/
poj 3897 Maze Stretching 二分+A*搜索的更多相关文章
- {POJ}{3897}{Maze Stretching}{二分答案+BFS}
题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...
- POJ 3273 Monthly Expense二分查找[最小化最大值问题]
POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...
- POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9658 Accepted: ...
- 搜索 || BFS || POJ 2157 Maze
走迷宫拿宝藏,拿到所有对应的钥匙才能开门 *解法:从起点bfs,遇到门时先放入队列中,取出的时候看钥匙够不够决定开不开门,如果不够就把它再放回队列继续往下走,当队列里只有几个门循环的时候就可以退出,所 ...
- POJ - 1426 Find The Multiple(搜索+数论)
转载自:優YoU http://user.qzone.qq.com/289065406/blog/1303946967 以下内容属于以上这位dalao http://poj.org/problem? ...
- POJ 3579 3685(二分-查找第k大的值)
POJ 3579 题意 双重二分搜索:对列数X计算∣Xi – Xj∣组成新数列的中位数 思路 对X排序后,与X_i的差大于mid(也就是某个数大于X_i + mid)的那些数的个数如果小于N / 2的 ...
- POJ 1088 滑雪(记忆化搜索)
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 92384 Accepted: 34948 Description ...
- hiho_1139_二分+bfs搜索
题目 给定N个点和M条边,从点1出发,到达点T.寻找路径上边的个数小于等于K的路径,求出所有满足条件的路径中最长边长度的最小值. 题目链接:二分 最小化最大值,考虑采用二分搜索.对所有的边长进 ...
- poj 3258 River Hopscotch(二分+贪心)
题目:http://poj.org/problem?id=3258 题意: 一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L. 河中有n块石头,每块石头到S都 ...
随机推荐
- PHP经验——获得PHP版本信息及版本比较
原文:PHP经验--获得PHP版本信息及版本比较 偶然看到别人写的一句代码: <?php if (version_compare("5.2", PHP_VERSION, &q ...
- 顶级jQuery树插件
顶级jQuery树插件 顶级jQuery树插件 2013-03-05 17:20 139人阅读 评论(0) 收藏 举报 jsTree JsTree是一个基于jQuery的Tree控件.支持HTML.J ...
- MVC+Bootstrap设计
MVC+Bootstrap) 二 框架设计 文章目录: 一.前言 二.结构图 三.项目搭建 四.代码生成 五.实现接口 六.依赖倒置 七.登录实现 八.最后 一.前言 这个框架是从最近几年做过的项目中 ...
- SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比
原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...
- Ajax.ActionLink 用法
Ajax.ActionLink 用法 Ajax 属性的ActionLink方法可以创建一个具有异步行为的锚标签. ActionLink方法的第一个参数指定了链接文本,第二个参数是要异步调用的操作的名称 ...
- 基于C# 语言的两个html解析器
基于C# 语言的两个html解析器 1)Html Agility Pack http://nsoup.codeplex.com/ 代码段示例: HtmlDocument doc = new HtmlD ...
- LINQ TO SQL ——Group by
原文:LINQ TO SQL --Group by 分组在SQL中应用的十分普遍,在查询,统计时都有可能会用到它.LINQ TO SQL中同样具备group的功能,这篇我来讲下LINQ TO SQL中 ...
- python进程池剖析(一)
python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...
- vi/vim多行注释和取消注释
多行注释: 1. 进入命令行模式,按ctrl + v进入 visual block模式,然后按j, 或者k选中多行,把需要注释的行标记起来 2. 按大写字母I,再插入注释符,例如// 3. 按esc键 ...
- 订单处理(c#实现)
State模式的经典应用场景:订单处理(c#实现) State模式在对象内部状态发生变化的时候,改变自身的行为,这通常是通过切换内部状态对象实现的,对象将自身在各个状态的行为推给了状态对象,从而解开了 ...