【Code Forces 320C】【贪心+讨论】A Problem about Polyline 点在折线段上求最小的波浪长度
2015-09-17 15:50
197 查看
【传送门】
http://codeforces.com/contest/579/problem/C
【题意】
给你一段波浪线,点数变化情况是——
(0,0)->(x,x)->(2x,0)->(3x,x)
也就是,先以1的斜率递增长度x,再以-1的斜率递减长度x,
再给你一个点(a,b),让你输出尽可能小的x,使得(a,b)在这样的折线上。
【类型】
贪心+讨论
【分析】
首先x>=b是一定的,
然后为了方便,我们把(a,b)映射到x轴上
我们不知道(a,b)是在上升段还是下降段,
所以映射有两种——
(1)a-=b;
(2)a+=b;
然后a就是横坐标了
而不管a是-=b还是+=b,现在的a肯定都将是2x的整数倍,我们是希望使得x尽可能小,也就是这个倍数尽可能大。
然而这里有一个限定条件,x>=b
所以我们假定x=b,这种情况下x最小,倍数也会尽可能大。
于是我们求出这个倍数(因为要求是整数),然后再求出其对应的x,并更新答案。
【时间复杂度&&优化】
O(1)
这题的标程,代码只有2行——
咦,其实和我之前写的代码一样,但是简化了,不用再考虑a-b
为什么呢?
因为可以总结为——
一定是把这个点向最右端映射才最优。
为什么呢?
首先不论向左还是向右映射,都是恰好要求是2kx的位置,
然后x是有最小值的,所以我们能求得k的最大值,并且向下取整得到最大可能的整数k。
然后答案的映射是
k1=[(a-b)/(2b)]
k2=[(a+b)/(2b)]
v1=(a-b)/k1
v2=(a+b)/k2
k2一定比k1大1
而且k2/k1 >= (a+b)/(a-b) (分母与分子差固定,分母与分子越接近数值就越大)
于是在(a-b)/k1与(a+b)/(k1+1)的大小比较的时候
必然有(a-b)/k1 >= (a+b)/k2
取(a+b)/k2即可,于是就有了2行代码的标程
【trick】
然而这道题有一个点比较特殊,就是——
我们算出倍数k之后,有if(k)gmin(ans,lft/(2.0*k));
因为涉及到除法,所以这里k必须要求是整数。
然而k是可能为0而且合法的,这种情况出现在a=b的时候,有的写法会在这里卡住,特判一下即可
【数据】
Input
3 1
Output
1.000000000000
Input
1 3
Output
-1
Input
4 1
Output
1.250000000000
【代码】
http://codeforces.com/contest/579/problem/C
【题意】
给你一段波浪线,点数变化情况是——
(0,0)->(x,x)->(2x,0)->(3x,x)
也就是,先以1的斜率递增长度x,再以-1的斜率递减长度x,
再给你一个点(a,b),让你输出尽可能小的x,使得(a,b)在这样的折线上。
【类型】
贪心+讨论
【分析】
首先x>=b是一定的,
然后为了方便,我们把(a,b)映射到x轴上
我们不知道(a,b)是在上升段还是下降段,
所以映射有两种——
(1)a-=b;
(2)a+=b;
然后a就是横坐标了
而不管a是-=b还是+=b,现在的a肯定都将是2x的整数倍,我们是希望使得x尽可能小,也就是这个倍数尽可能大。
然而这里有一个限定条件,x>=b
所以我们假定x=b,这种情况下x最小,倍数也会尽可能大。
于是我们求出这个倍数(因为要求是整数),然后再求出其对应的x,并更新答案。
【时间复杂度&&优化】
O(1)
这题的标程,代码只有2行——
[code]if(a<b)puts("-1"); else printf("%.12f\n",(a+b)/(2.*((a+b)/(2*b))));
咦,其实和我之前写的代码一样,但是简化了,不用再考虑a-b
为什么呢?
因为可以总结为——
一定是把这个点向最右端映射才最优。
为什么呢?
首先不论向左还是向右映射,都是恰好要求是2kx的位置,
然后x是有最小值的,所以我们能求得k的最大值,并且向下取整得到最大可能的整数k。
然后答案的映射是
k1=[(a-b)/(2b)]
k2=[(a+b)/(2b)]
v1=(a-b)/k1
v2=(a+b)/k2
k2一定比k1大1
而且k2/k1 >= (a+b)/(a-b) (分母与分子差固定,分母与分子越接近数值就越大)
于是在(a-b)/k1与(a+b)/(k1+1)的大小比较的时候
必然有(a-b)/k1 >= (a+b)/k2
取(a+b)/k2即可,于是就有了2行代码的标程
【trick】
然而这道题有一个点比较特殊,就是——
我们算出倍数k之后,有if(k)gmin(ans,lft/(2.0*k));
因为涉及到除法,所以这里k必须要求是整数。
然而k是可能为0而且合法的,这种情况出现在a=b的时候,有的写法会在这里卡住,特判一下即可
【数据】
Input
3 1
Output
1.000000000000
Input
1 3
Output
-1
Input
4 1
Output
1.250000000000
【代码】
[code]#include<stdio.h> #include<iostream> #include<string.h> #include<ctype.h> #include<math.h> #include<map> #include<set> #include<vector> #include<queue> #include<functional> #include<string> #include<algorithm> #include<time.h> #include<bitset> void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);} #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T> inline void gmax(T &a,T b){if(b>a)a=b;} template <class T> inline void gmin(T &a,T b){if(b<a)a=b;} using namespace std; const int N=0,M=0,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;const double eps=1e-8,PI=acos(-1.0);//.0 int a,b; int main() { while(~scanf("%d%d",&a,&b)) { int x=a+b; int k=x/(b<<1); if(k)printf("%.12f\n",x/(2.0*k)); else printf("-1\n"); } return 0; }
相关文章推荐
- git怎样删除未监视的文件untracked files
- 切图那点事
- Windchill的历史
- Effective Java学习笔记
- struts2文件上传
- 幸福是什么
- GirdView代码分析
- [JS插件] fullPage:适合移动端web整屏滚动组件
- 安畅亚太节点即将上线,战略布局海外市场
- [BLE--GAP]GAP Service及其使用
- Maven+Spring framework生成的可执行jar文件执行异常
- Effective C++ ——初始化
- Makefile使用总结
- GetComponentsInChildren(); 使用方法
- 输出全排列的方案
- linux yum命令详解
- APP开发中设计规范的重要性
- 注册表
- Spring-IOC容器的配置
- openwrt_4M_flash启动log