题意,给你一个l,和一个地图,让你从起点走到终点,使得路程刚好等于l。

你可以选择一个系数,把纵向的地图拉伸或收缩,比如你选择系数0.5,也就是说现在上下走一步消耗0.5的距离,如果选择系数3,也就是说上下一步消耗3的距离。

左右不能改变。

Hint中提示了答案在0--10之间,其实就透露出了二分的思想。

我们对系数P进行二分,对每一个系数P进行一次bfs,如果可以在小于等于l的步数内找到解,则增加下界,否则减小上界。

由于上下和左右的消耗值不相同,所以我们采用A*算法,设估价值为当前点到目标点的哈弗曼距离(注意上下距离要乘上系数P),然后利用优先队列搜索。

我试了几下,精度开到1e-6才不会wa

如果用普通的bfs做,注意不能一遇到终点就结束,有可能丢失掉最优解。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<queue>
  5. #include<cmath>
  6. #include<iostream>
  7. using namespace std;
  8. char map[105][105];
  9. int CAS;
  10. double l;
  11. int n,len;
  12. int end,st;
  13. int dx[]={-1,1,0,0};
  14. int dy[]={0,0,-1,1};
  15. struct node
  16. {
  17. double dis;
  18. int x;
  19. int y;
  20. double h;
  21. bool operator < (const node &a) const
  22. {
  23. return dis+h>a.dis+h;
  24. }
  25. }start;
  26. double geth(int x,int y,double k)
  27. {
  28. double h=0;
  29. int ex=end/len;
  30. int ey=end%len;
  31. return abs(ey-y)+abs(ex-x)*k;
  32. }
  33. bool isok(int x,int y)
  34. {
  35. return x>=0&&x<n&&y>=0&&y<len&&map[x][y]!='#';
  36. }
  37. double vis[105][105];
  38. bool bfs(double k)
  39. {
  40. for(int i=0;i<n;i++)
  41. for(int j=0;j<len;j++)
  42. vis[i][j]=100000000;
  43. priority_queue<node> q;
  44. q.push(start);
  45. vis[start.x][start.y]=1;
  46. node tmp,tt;
  47. while(!q.empty())
  48. {
  49. tmp=q.top();q.pop();
  50. for(int d=0;d<4;d++)
  51. {
  52. tt=tmp;
  53. tt.x=tmp.x+dx[d];
  54. tt.y=tmp.y+dy[d];
  55. if(isok(tt.x,tt.y))
  56. {
  57. tt.h=geth(tt.x,tt.y,k);
  58. if(d<=1) tt.dis+=k;
  59. else tt.dis+=1;
  60. if(tt.dis<vis[tt.x][tt.y]) vis[tt.x][tt.y]=tt.dis;
  61. else continue;
  62.  
  63. if(tt.x==end/len&&tt.y==end%len)
  64. {
  65. if(tt.dis<=l) return true;
  66. else return false;
  67. }
  68. q.push(tt);
  69. }
  70. }
  71. }
  72. return false;
  73. }
  74. int main()
  75. {
  76. int cas;
  77. CAS=1;
  78. scanf("%d",&cas);
  79. while(cas--)
  80. {
  81. scanf("%lf%d",&l,&n);getchar();
  82. for(int i=0;i<n;i++)
  83. gets(map[i]);
  84. len=strlen(map[0]);
  85. for(int i=0;i<n;i++)
  86. for(int j=0;j<len;j++)
  87. {
  88. if(map[i][j]=='S')
  89. {
  90. st=i*len+j;
  91. }
  92. if(map[i][j]=='E')
  93. {
  94. end=i*len+j;
  95. }
  96. }
  97. start.dis=0;
  98. start.x=st/len;
  99. start.y=st%len;
  100. double l=0;
  101. double r=11;
  102. double mid=(l+r)/2.0;
  103. while(r-l>1e-6)
  104. {
  105. // cout<<l<<' '<<r<<' '<<mid<<endl;
  106. mid=(l+r)/2.0;
  107. if(bfs(mid)) l=mid;
  108. else r=mid;
  109. }
  110. printf("Case #%d: %.3f%%\n",CAS++,mid*100);
  111. }
  112. return 0;
  113. }

/*

我是一只奔跑的小菜鸡……

*/

poj 3897 Maze Stretching 二分+A*搜索的更多相关文章

  1. {POJ}{3897}{Maze Stretching}{二分答案+BFS}

    题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...

  2. POJ 3273 Monthly Expense二分查找[最小化最大值问题]

    POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...

  3. POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)

    Secret Milking Machine Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9658   Accepted: ...

  4. 搜索 || BFS || POJ 2157 Maze

    走迷宫拿宝藏,拿到所有对应的钥匙才能开门 *解法:从起点bfs,遇到门时先放入队列中,取出的时候看钥匙够不够决定开不开门,如果不够就把它再放回队列继续往下走,当队列里只有几个门循环的时候就可以退出,所 ...

  5. POJ - 1426 Find The Multiple(搜索+数论)

    转载自:優YoU  http://user.qzone.qq.com/289065406/blog/1303946967 以下内容属于以上这位dalao http://poj.org/problem? ...

  6. POJ 3579 3685(二分-查找第k大的值)

    POJ 3579 题意 双重二分搜索:对列数X计算∣Xi – Xj∣组成新数列的中位数 思路 对X排序后,与X_i的差大于mid(也就是某个数大于X_i + mid)的那些数的个数如果小于N / 2的 ...

  7. POJ 1088 滑雪(记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 92384   Accepted: 34948 Description ...

  8. hiho_1139_二分+bfs搜索

    题目 给定N个点和M条边,从点1出发,到达点T.寻找路径上边的个数小于等于K的路径,求出所有满足条件的路径中最长边长度的最小值. 题目链接:二分     最小化最大值,考虑采用二分搜索.对所有的边长进 ...

  9. poj 3258 River Hopscotch(二分+贪心)

    题目:http://poj.org/problem?id=3258 题意: 一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L. 河中有n块石头,每块石头到S都 ...

随机推荐

  1. PHP经验——获得PHP版本信息及版本比较

    原文:PHP经验--获得PHP版本信息及版本比较 偶然看到别人写的一句代码: <?php if (version_compare("5.2", PHP_VERSION, &q ...

  2. 顶级jQuery树插件

    顶级jQuery树插件 顶级jQuery树插件 2013-03-05 17:20 139人阅读 评论(0) 收藏 举报 jsTree JsTree是一个基于jQuery的Tree控件.支持HTML.J ...

  3. MVC+Bootstrap设计

    MVC+Bootstrap) 二 框架设计 文章目录: 一.前言 二.结构图 三.项目搭建 四.代码生成 五.实现接口 六.依赖倒置 七.登录实现 八.最后 一.前言 这个框架是从最近几年做过的项目中 ...

  4. SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

    原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...

  5. Ajax.ActionLink 用法

    Ajax.ActionLink 用法 Ajax 属性的ActionLink方法可以创建一个具有异步行为的锚标签. ActionLink方法的第一个参数指定了链接文本,第二个参数是要异步调用的操作的名称 ...

  6. 基于C# 语言的两个html解析器

    基于C# 语言的两个html解析器 1)Html Agility Pack http://nsoup.codeplex.com/ 代码段示例: HtmlDocument doc = new HtmlD ...

  7. LINQ TO SQL ——Group by

    原文:LINQ TO SQL --Group by 分组在SQL中应用的十分普遍,在查询,统计时都有可能会用到它.LINQ TO SQL中同样具备group的功能,这篇我来讲下LINQ TO SQL中 ...

  8. python进程池剖析(一)

    python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...

  9. vi/vim多行注释和取消注释

    多行注释: 1. 进入命令行模式,按ctrl + v进入 visual block模式,然后按j, 或者k选中多行,把需要注释的行标记起来 2. 按大写字母I,再插入注释符,例如// 3. 按esc键 ...

  10. 订单处理(c#实现)

    State模式的经典应用场景:订单处理(c#实现) State模式在对象内部状态发生变化的时候,改变自身的行为,这通常是通过切换内部状态对象实现的,对象将自身在各个状态的行为推给了状态对象,从而解开了 ...