传送门

题目大意

给定网格图上起点和终点每个格子是长为$100$米的正方形,你可以沿着线走。

平面上还有若干个关键点,以每个关键点为圆心,$10$为半径画圆,表示不能进入圆内的线,但是可以从圆周上走,求起点到终点的最短距离。

保证任意两个关键点不在同一条水平或竖直的线上。

题解

先通过翻转网格图使得起点$S$在终点$Y$的左下方,由于有任意两两关键点不在同一水平竖直的线上,通过简单计算发现,我们只可能往右或往上冲着最终的终点走。

随意我们只需要横纵坐标都在起点终点之间的关键点即可。

对于一个关键点,如果经过它转$90°$,那么路程的长度就会减少,如果绕过半圆继续直走,那么路程长度就会增加。

我们贪心取关键点。由于起点在左下方,终点在右上方,每次向右上方走,那么最终经过的关键点一定是一个上升的序列。

我们只需要求这个上升的序列的长度即可。

答案等于起点终点的曼哈顿距离$-$经过关键点的数量$\times$绕$90$度省去的路程。

注意,当最长上升子序列的长度达到$\min\{Y_T-Y_S+1,X_T-X_S+1\}$时,说明至少绕过一个关键点的半圆,需要特判。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #define LL long long
  7. #define M 200020
  8. using namespace std;
  9. namespace IO{
  10. const int BS=(1<<20)+5; int Top=0;
  11. char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
  12. char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
  13. void flush(){fwrite(OT,1,OS-OT,stdout);}
  14. void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
  15. void write(int x){
  16. if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
  17. while(x) SS[++Top]=x%10,x/=10;
  18. while(Top) Putchar(SS[Top]+'0'),--Top;
  19. }
  20. int read(){
  21. int nm=0,fh=1; char cw=Getchar();
  22. for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
  23. for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
  24. return nm*fh;
  25. }
  26. }
  27. using namespace IO;
  28. const double D=11.4159265358979323846264338328;
  29. const double K=-4.2920367320510338076867830836;
  30. int n,m,maxy,sx,sy,ex,ey,tot,c[M],pos[M],now; double ans;
  31. struct pot{
  32. int X,Y; void gtin(){X=read(),Y=read(),maxy=max(maxy,Y+1);}
  33. bool ft(){return X>=sx&&X<=ex&&Y>=sy&&Y<=ey;}
  34. bool operator <(const pot&ot)const{return X<ot.X;}
  35. }p[M],t[M];
  36. int main(){
  37. sx=read(),sy=read(),ex=read(),ey=read(),maxy=max(sy,ey);
  38. if(sx>ex) swap(sx,ex),swap(sy,ey); n=read();
  39. for(int i=1;i<=n;i++) p[i].gtin();
  40. if(sy>ey){
  41. for(int i=1;i<=n;i++) p[i].Y=maxy-p[i].Y;
  42. sy=maxy-sy,ey=maxy-ey;
  43. } sort(p+1,p+n+1),ans=(ey+ex-sy-sx)*100.0;
  44. for(int i=1;i<=n;i++) if(p[i].ft()) t[++tot]=p[i];
  45. memset(c,0x3f,sizeof(c)),c[0]=now=0;
  46. for(int i=1;i<=tot;i++){
  47. int l=1,r=now,md,res=0;
  48. while(l<=r){md=((r+l)>>1);if(c[md]<t[i].Y) res=md,l=md+1;else r=md-1;}
  49. if(res==now) now++; c[res+1]=min(c[res+1],t[i].Y);
  50. }
  51. if(now<=ex-sx&&now<=ey-sy) ans+=now*K;
  52. else ans+=(now-1)*K+D; printf("%.13lf\n",ans);
  53. return 0;
  54. }

Agc019_C Fountain Walk的更多相关文章

  1. [AtCoder 2702]Fountain Walk - LIS

    Problem Statement In the city of Nevermore, there are 108 streets and 108 avenues, both numbered fro ...

  2. 【agc019C】Fountain Walk

    Portal --> agc019C Description 有一个\(10^8*10^8\)的网格图,一格距离为\(100\),第\(x\)条竖线和第\(y\)条横线的交点记为\((x,y)\ ...

  3. 【AtCoder】AGC019

    A - Ice Tea Store 算一下每种零售最少的钱就行,然后优先买2,零头买1 #include <bits/stdc++.h> #define fi first #define ...

  4. python os.walk()

    os.walk()返回三个参数:os.walk(dirpath,dirnames,filenames) for dirpath,dirnames,filenames in os.walk(): 返回d ...

  5. LYDSY模拟赛day1 Walk

    /* 依旧考虑新增 2^20 个点. i 只需要向 i 去掉某一位的 1 的点连边. 这样一来图的边数就被压缩到了 20 · 2^20 + 2n + m,然后 BFS 求出 1 到每个点的最短路即可. ...

  6. How Google TestsSoftware - Crawl, walk, run.

    One of the key ways Google achievesgood results with fewer testers than many companies is that we ra ...

  7. poj[3093]Margaritas On River Walk

    Description One of the more popular activities in San Antonio is to enjoy margaritas in the park alo ...

  8. os.walk()

    os.walk() 方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下. walk()方法语法格式如下: os.walk(top[, topdown=True[, onerror=None[ ...

  9. 精品素材:WALK & RIDE 单页网站模板下载

    今天,很高兴能向大家分享一个响应式的,简约风格的 HTML5 单页网站模板.Walk & Ride 这款单页网站模板是现代风格的网页模板,简洁干净,像素完美,特别适合用于推广移动 APP 应用 ...

随机推荐

  1. Spring boot cassandra - nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException

    1.在Pom.xml添加spring-boot-starter-data-cassandra依赖: <dependency> <groupId>org.springframew ...

  2. vimium的使用介绍和基本用法

    vimium是chrome浏览器的一个插件,fq去chrome应用商店搜索vimium,下载安装 纯键盘操作,脱离了鼠标,提高效率 核心是f,安装好vimium后只需要按f,输入对应的编号就能进入相应 ...

  3. 使用BUCK进行iOS项目打包

    关于BUCK BUCK是Facebook开源的快速打包工具,可以用于多种语言及平台的项目打包,例如:C.C++.Java.iOS.Android等等.用于大型的iOS.Android项目,可以显著提升 ...

  4. UI设计中的各种小控件

    xib支持图形化操作,提供了几乎所有的控件可供选择,只需拖动到相应的位置即可,但是控件的后台代码仍然需要手动编写,一定程度上加速了前台的开发. xib快速开发程序,手写代码速度比较慢 xib适合做静态 ...

  5. github资源下载速度慢的解决办法

    xx-net:https://github.com/XX-net/XX-Net

  6. 查看linux系统版本信息(Oracle Linux、Centos Linux、Redhat Linux、Debian、Ubuntu)

    一.查看Linux系统版本的命令(3种方法) 1.cat /etc/issue,此命令也适用于所有的Linux发行版. [root@S-CentOS home]# cat /etc/issue Cen ...

  7. 虚构 css 父级选择器

    能 CSS 解决的绝不用 JS,这句话又一次故作装逼地说出来还是挺爽的... 比如下拉列表,能用 CSS 的 :focus 就不用 JS 的 .on("focus blur") 能 ...

  8. 使用bedtools的一个问题

    问题:有两个平行测序样本,分别得到1.vcf和2.vcf两个文件,想知道这两个文件有多少个重合点. [wangjq@mgmt CHG029194]$ cat t1 chr1 10 10 chr1 11 ...

  9. Cocos2d-x项目移植到WP8系列之七:中文显示乱码

    原文链接:http://www.cnblogs.com/zouzf/p/3984628.html C++和C#互调时经常会带一些参数过去例如最常见的字符串,如果字符串里有中文的话,会发现传递过去后变成 ...

  10. 【codevs1069】关押罪犯[noip2010](并查集)

    题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨 ...