[日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何
题意:给一条平面内$n$个点的折线,要求在折线上搞一个高度$h$的瞭望塔,能够看见折线上所有的点,求$h$的最小值($n \leq 300$)
updata2018.1.21
正解半平面交在另一篇里面…
updata2018.1.5
我发现这题可以随便乱搞过掉…(雾
把所有折线段的$n$条直线求出来,求他们两两之间的交点(这些交点也包括了折线上的折点)和两端的横坐标丢到一个数组$q[]$
答案的横坐标一定在$q[]$里(如果答案在某两个之间的话一定不会更优)
时间复杂度$O(n^3)$…相当暴力
INF不要开小…啧啧啧
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; const int N=305;
struct line
{
double k,b;
line(){}
void calc(double x1,double y1,double x2,double y2)
{
k=(y1-y2)/(x1-x2);
b=y1-k*x1;
}
double f(double x)
{
return k*x+b;
}
}ls[N];
int n,tot;
double xs[N],ys[N],q[N*N],ans;
inline double high(double x)
{
double res=0;
for(register int i=1;i<n;i++)res=max(res,ls[i].f(x));
return res;
}
inline double f(double x)
{
for(register int i=1;i<n;i++)if(xs[i]<=x&&x<=xs[i+1])return ls[i].f(x);
return 0;
}
int main()
{
scanf("%d",&n);ans=1e11;
for(register int i=1;i<=n;i++)scanf("%lf",&xs[i]);
for(register int i=1;i<=n;i++)scanf("%lf",&ys[i]);
for(register int i=1;i<n;i++)ls[i].calc(xs[i],ys[i],xs[i+1],ys[i+1]);
for(register int i=1;i<n;i++)
{
for(register int j=i+1;j<n;j++)if(ls[i].k!=ls[j].k)
{
double x=(ls[j].b-ls[i].b)/(ls[i].k-ls[j].k);
if(xs[1]<=x&&x<=xs[n])q[++tot]=x;
}
}q[++tot]=xs[1];q[++tot]=xs[n];
for(register int i=1;i<=tot;i++)if(q[i]!=q[i-1])
{
double cur=fabs(high(q[i])-f(q[i]));
ans=min(ans,cur);
}printf("%.3lf",ans);
return 0;
}
跑得比之前写的不知道快到哪里去了
原文
听说正解平面半交,我不会啊做怎么办,Po姐教你模拟退火搞233
模拟退火随机横坐标,在纵坐标上二分高度
T_T然后注意细节不要写挂
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int N=305;
struct point
{
double x,y;
point(){}
point(double tx,double ty)
{
x=tx;y=ty;
}
}ps[N];
inline point operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
struct line
{
point p1,p2;
double k,b;
void calc()
{
point p=p1-p2;
k=p.y/p.x;
b=p2.y-k*p2.x;
}
}ls[N];
int n;
double now,ansx,ansy; inline double Rand()
{
return (rand()%1000)/1000.0;
}
inline double f(line l,double x)
{
return l.k*x+l.b;
}
inline double f(double x)
{
for(register int i=2;i<=n;i++)
if(ls[i].p1.x<=x&&x<=ls[i].p2.x)return f(ls[i],x);
return 0;
}
inline double operator * (point p1,point p2)
{
return p1.x*p2.y-p1.y*p2.x;
}
inline bool judge(double x,double mid)
{
point p(x,mid);
for(register int i=2;i<=n;i++)
if((ps[i-1]-p)*(ps[i]-p)<0)
return 0;
return 1;
}
inline double check(double x)
{
double temp,l,r,mid;
temp=f(x);l=temp;r=1e11;
while(r-l>(1e-7))
{
mid=(l+r)/2;
if(judge(x,mid))r=mid;
else l=mid;
}
mid-=temp;
if(mid<ansy)ansx=x,ansy=mid;
return mid;
}
inline void SA()
{
double t=ps[n].x-ps[1].x;
while(t>(1e-5))
{
double temp=now+t*(Rand()*2-1);
if(temp<ps[1].x||temp>ps[n].x)continue;
double dE=check(now)-check(temp);
if(dE>0||exp(dE/t)>Rand())
now=temp;
t*=0.99;
}
t*=10;
for(register int i=1;i<=1000;i++,t*=0.99)
{
double temp=ansx+t*(Rand()*2-1);
if(temp<ps[1].x||temp>ps[n].x)continue;
check(temp);
}
}
int main()
{
//freopen("input.in","r",stdin);
//srand(19260817);
scanf("%d",&n);
for(register int i=1;i<=n;i++)scanf("%lf",&ps[i].x);
for(register int i=1;i<=n;i++)scanf("%lf",&ps[i].y);
for(register int i=2;i<=n;i++)ls[i].p1=ps[i-1],ls[i].p2=ps[i],ls[i].calc();
ansy=1e11;ansx=now=(ps[n].x-ps[1].x)/2;SA();
printf("%.3lf",ansy+(1e-7));
return 0;
}
等学了平面半交再来更新
[日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何的更多相关文章
- [日常摸鱼]bzoj1038[ZJOI2008]瞭望塔-半平面交
		
这回好好用半平面交写一次- 看了cls当年写的代码看了好久大概看懂了-cls太强辣 #include<cstdio> #include<iostream> #include&l ...
 - [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
		
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2999 Solved: 1227[Submit][Statu ...
 - bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
		
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...
 - bzoj1038: [ZJOI2008]瞭望塔
		
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
 - 【半平面交】bzoj1038 [ZJOI2008]瞭望塔
		
http://m.blog.csdn.net/blog/qpswwww/44105605 #include<cstdio> #include<cmath> #include&l ...
 - BZOJ-1038 [ZJOI2008]瞭望塔
		
先求半平面交,然后建塔的地方肯定是在半平面交的交点上或者是在地面线段的交点上. #include <cstdlib> #include <cstdio> #include &l ...
 - [日常摸鱼]bzoj1036 [ZJOI2008]树的统计Count
		
听说后天会考x 省选居然还考模板题的么(好吧好像NOI也有考而且也是树剖-) 题意:一棵树,每个点有权值,三种操作:单点修改.求链上最大值.求链上权值和. 直接上模板. 我可能不会写单点修改的线段树了 ...
 - 【BZOJ1038】[ZJOI2008]瞭望塔 半平面交
		
[BZOJ1038][ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如 ...
 - 【bzoj1038】瞭望塔
		
[bzoj1038]瞭望塔 题意 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折 ...
 
随机推荐
- 凭借着这份面经,我拿下了字节,美团的offer!
			
最近经常有粉丝私信问我问了一些诸如秋招该怎么复习的问题,我就想顺便把回答整理发一发.我也是把之前面试的一些经历经验和身边的人面试的经验总结了一下放在下面. 前期准备规划: 如果秋招的话一般过年回来就可 ...
 - 通过RayFire为图形添加二次破碎效果
			
在完成3D建模之后,RayFire能帮助用户制作多种类型的破碎效果,如均匀碎片.放射状碎片.木碎等效果.另外,用户还可以利用RayFire的碎片选取功能,为图形进行二次破碎,以达到增加局部碎片的效果. ...
 - 用FL Studio来给电子音乐混音的方法
			
FL Studio也算是音乐人用的比较多的编曲.混音软件了,FL Studio的一大的特色就是电子音乐的制作.尤其是对混音的操作,混音是电音制作过程中一个非常重要的环节,非常重要. 混音是什么?混音的 ...
 - FL Studio里一起安装的ASIO4ALL有什么用?
			
在我们安装FL Studio时,正常情况下我们安装FL Studio时最多也就改改安装目录,其他的安装设置一般不会动,但看到FL安装的那些东西我们难道不会感到好奇吗?FL Studio安装包括FL S ...
 - FL Studio中有关Sub Bass的一些制作与混音技巧
			
1.Sub Bass是什么? Sub Bass是一种低沉的低音,其频率大约低于60赫兹,并向下延伸,包括人类所能听到的最低频率,约为20赫兹.在这个范围内,人类的听觉不是很灵敏,所以在这个范围内的声音 ...
 - Linux中的基本命令无法使用,报Command not found的错误的解决方法
			
一般我们在Linux中执行命令的时候,会报 Command not found 的错误,报这种错误一般有两种原因:一是你的系统中没有安装这个命令,需要你手动安装,另外一种原因就是平常这些命令用着好好的 ...
 - 【论文解读】【半监督学习】【Google教你水论文】A Simple Semi-Supervised Learning Framework for Object Detection
			
题记:最近在做LLL(Life Long Learning),接触到了SSL(Semi-Supervised Learning)正好读到了谷歌今年的论文,也是比较有点开创性的,浅显易懂,对比实验丰富, ...
 - c++11-17 模板核心知识(十一)—— 编写泛型库需要的基本技术
			
Callables 函数对象 Function Objects 处理成员函数及额外的参数 std::invoke<>() 统一包装 泛型库的其他基本技术 Type Traits std:: ...
 - moviepy音视频剪辑:输出文件前预览剪辑和视频帧的preview和imdisplay方法
			
☞ ░ 前往老猿Python博文目录 ░ 一.引言 由于moviepy合成剪辑后,输出需要较多的时间,那么在输出前预览一下有助于提高处理效率.moviepy提供了预览的工具,这个工具是基于pygame ...
 - requests的再次学习
			
title: requests模块的再次理解 date: 2020-03-10 22:44:26 tags: 1.response的解析 当requests模块发送请求后,我们会对其响应的数据也就是r ...