嘻嘻嘻嘻,从读题到过题大概一个小时?

这套题题面太长了。。。就挑短的写。。

题意很简单。   给出平面上n个点,求一个面积最小的平行四边形覆盖这n个点。

显然要先求凸包。

然后枚举边就可以了。我一开始脑子抽了,只枚举了相邻的。。(今天下午四点多才吃上早饭很痛苦。感觉神智不清,昨晚补题补到3点。。。)

然后我们要 分别找出 离这两条边最远的 点吧,然后通过简单的平移操作求直线交点,再用叉积搞一下就阔以了。

虽然理论上 n^3不会t,但我还是t了。。。所以我们先预处理出来离每条边最远的点是哪一个。就阔以了。

记得特判一下没有凸包的情况,虽然不知道有没有这种数据。。。

 #include <bits/stdc++.h>
using namespace std;
typedef double db;
const db eps=1e-;
const db pi=acos(-);
int sign(db k){
if (k>eps) return ; else if (k<-eps) return -; return ;
}
int cmp(db k1,db k2){return sign(k1-k2);}
struct point{
db x,y;
point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
point operator * (db k1) const{return (point){x*k1,y*k1};}
point operator / (db k1) const{return (point){x/k1,y/k1};}
db abs(){return sqrt(x*x+y*y);}
db dis(point k1){return ((*this)-k1).abs();}
point turn90(){ return point{-y,x};}
db getP()const { return sign(y)==||(sign(y)==&&sign(x)==-);}
point unit(){db w=abs(); return point{x/w,y/w};}
db abs2(){return x*x+y*y;}
bool operator < (const point k1) const{
int a=cmp(x,k1.x);
if (a==-) return ; else if (a==) return ; else return cmp(y,k1.y)==-;
}
};
db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
db rad(point k1,point k2){ return atan2(cross(k1,k2),dot(k1,k2));}
int compareangle(point k1,point k2){
return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>);
}
point proj(point k1,point k2,point q){ // q 到直线 k1,k2 的投影
point k=k2-k1; return k1+k*(dot(q-k1,k)/k.abs2());
}
point getLL(point k1,point k2,point k3,point k4){
db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3);
return (k1*w2+k2*w1)/(w1+w2);
}
struct line{
point p[];
line(point k1,point k2){p[]=k1;p[]=k2;}
point &operator[](int k){ return p[k];}
int include(point k){ return sign(cross(p[]-p[],k-p[])>);}
point dir(){ return p[]-p[];}
line push(db eps){//向左手边平移eps
//const db eps=1e-6;
point delta=(p[]-p[]).turn90().unit()*eps;
return {p[]-delta,p[]-delta};
}
};
point getLL(line k1,line k2){
return getLL(k1[],k1[],k2[],k2[]);
}
int parallel(line k1,line k2){ return sign(cross(k1.dir(),k2.dir()))==;}
int sameDir(line k1,line k2){
return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==;
}
int operator <(line k1,line k2){
if(sameDir(k1,k2))return k2.include(k1[]);
return compareangle(k1.dir(),k2.dir());
}
int checkpos(line k1,line k2,line k3){ return k3.include(getLL(k1,k2));}
vector<point> convexHull(vector<point>ps){
int n = ps.size();if(n<=)return ps;
sort(ps.begin(),ps.end());
vector<point> qs(n*);int k=;
for(int i=;i<n;qs[k++]=ps[i++])
while (k>&&cross(qs[k-]-qs[k-],ps[i]-qs[k-])<=)--k;
for(int i=n-,t=k;i>=;qs[k++]=ps[i--])
while (k>t&&cross(qs[k-]-qs[k-],ps[i]-qs[k-])<=)--k;
qs.resize(k-);
return qs;
}
int t,n;
vector<point> p;point s1,t1,s2,t2;
map<pair<int,int>,int> mp;
db check(int a,int b,int c,int d){
int id1=mp[make_pair(a,b)],id2=mp[make_pair(c,d)];
s1=p[id1],s2=p[id1]+p[a]-p[b];
point t1 = getLL(p[c],p[d],s1,s2);//一个交点
s1 = p[id2],s2=p[id2]+p[c]-p[d];
point t2 = getLL(p[a],p[b],s1,s2);
point bb = getLL(p[a],p[b],p[c],p[d]);
db S = abs(cross(bb-t1,bb-t2));
return S;
}
void init(){
int m = p.size();
for(int i=;i<m;i++){
db mx = ;int id=-;
for(int j=;j<m;j++){
db tmp = p[j].dis(proj(p[i],p[(i+)%m],p[j]));
if(cmp(tmp,mx)>){
mx=tmp,id=j;
}
}
mp[make_pair(i,(i+)%m)]=id;
}
}
point tmp;
int main(){
scanf("%d",&t);
for(int cas=;cas<=t;cas++){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%lf%lf",&tmp.x,&tmp.y);
p.push_back(tmp);
}
p=convexHull(p);
if(p.size()<){
printf("Swarm %d Parallelogram Area: 0.0000\n",cas);
continue;
}
init();
db ans = 1e15;
int m = p.size();
for(int i=;i<m;i++){
for(int j=i+;j<m;j++) {
ans = min(ans,check(i, (i + ) % m, j,(j+)%m));
}
}
printf("Swarm %d Parallelogram Area: %.4f\n",cas,ans);
p.clear();mp.clear();
}
}
/**
1
4
0 0
0 1
0 2
0 3
*/

gym101657 C的更多相关文章

随机推荐

  1. C#设置WebBrowser IE浏览器版本

    通过修改注册表的值,来指定winform程序打开的webBrowser的IE版本 1>方法一,通过程序修改注册表的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  2. 如何修改maven的默认jdk版本

    问题: 1.创建maven项目的时候,jdk版本是1.5版本,而自己安装的是1.7或者1.8版本. 2.每次右键项目名-maven->update project 时候,项目jdk版本变了,变回 ...

  3. Scala编程进阶

    跳出循环语句的3种方法... 2 多维数组... 3 Java数组与Scala数组缓冲的隐式转换... 3 Java Map与Scala Map的隐式转换... 3 Tuple拉链操作... 4 内部 ...

  4. python接口自动化测试(四)-Cookie&Sessinon

    掌握了前面几节的的内容,就可以做一些简单的http协议接口的请求发送了,但是这些还不够.HTTP协议是一个无状态的应用层协议,也就是说前后两次请求是没有任何关系的,那如果我们测试的接口之前有相互依赖关 ...

  5. CentOS7配置防火墙

    使用命令的方式配置 ##Add firewall-cmd --permanent --zone=public --add-port=/tcp ##Remove firewall-cmd --perma ...

  6. Pilosa文档翻译(二)入门指南

    目录 开始 Pilosa 简单项目 创建架构(Create the Schema) 从CVS文件导入数据 做一些查询(Queries) 接下来做什么? Pilosa支持默认使用JSON的HTTP接口. ...

  7. 基于springboot整合的rabbitmq

    技术:springboot1.5.2 + maven3.0.5 + rabbitmq3.7.13 + jdk1.8   概述 RabbitMQ是对高级消息队列协议(Advanced Message Q ...

  8. 【jquery采坑】Ajax配合form的submit提交(微擎表单提交,ajax验证,submit提交)

    1.采坑:实现form的submit提交,在提交之前,进行ajax的不同校验,然后onsubmit=return check(),进行提交 1/1 目的:可以实现以 from的submit提交,然后还 ...

  9. Android Activity的4种启动模式

    Activity的启动模式 standard 默认标志的启动模式,每次startActivity都是创建一个新的activity的实例,适用于绝大数情况 singleTop 单一顶部,如果要开启的ac ...

  10. 理解Java注解类型

    一. 理解Java注解 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy ...