gym101657 C
嘻嘻嘻嘻,从读题到过题大概一个小时?
这套题题面太长了。。。就挑短的写。。
题意很简单。 给出平面上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的更多相关文章
随机推荐
- poj3009 Curling 2.0(很好的题 DFS)
https://vjudge.net/problem/POJ-3009 做完这道题,感觉自己对dfs的理解应该又深刻了. 1.一般来说最小步数都用bfs求,但是这题因为状态记录很麻烦,所以可以用dfs ...
- 解析 ViewTreeObserver 源码(上)
主要内容:ViewTreeObserver 是被用来注册监听视图树的观察者,在视图树发生全局改变时将收到通知.本文从 ViewTreeObserver 源码出发,带你剖析 ViewTreeObserv ...
- tmux终端工具的简单使用
Linux上管理和运行进程除了程序级别的守护进程之外,经常用到的有比如nohup &的方式,以及screen会话的方式,而Tmux正是一个非常优秀的终端进程管理的软件,和GNU screen类 ...
- openssl链接动态库的方法
错误:AES_set_decrypt_key 一. 编译时: 1. 不要在windows与linux共享区编译2. ./config no-asm -fPIC3. make 二. cp: cannot ...
- ValueError: output parameter for reduction operation logical_and has too many dimensions ?
https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.all.html#numpy.all 运行示例,却发生错误 import ...
- 设计模式之二十一:中介者模式(Mediator)
中介者模式:定义了一个对象.用来封装一系列对象的交互.中介者模式通过使对象之间不必显式引用减少了对象之间的耦合,而且同意你独立改变它们之间的交互. 中介者模式就是将对象之间的交互封装在了一个独立的对象 ...
- Mongodb系列- CRUD操作介绍
---恢复内容开始--- 一 Create 操作 在MongoDB中,插入操作的目标是一个集合. MongoDB中的所有写入操作在单个文档的层次上都是原子的. For examples, see In ...
- What is a Back Order
What is a Back Order A back order is a customer order that has not been fulfilled. A back order gene ...
- Spark 官方博文专区(目录)
关于转载一些 Spark 官方的文档以及 DataBricks 公司博文,本系列基本是中英双语,主要是为了提高自己的英语水平. 文章分类 spark databricks A Tale of Thre ...
- PhpStorm连接Docker容器配置xdebug断点调试
本教程主要演示xdebug在PhpStorm中配置方法. 一.环境说明 1.Mac笔记本(本教程演示过程使用的是Mac OS操作系统,和windows环境是有区别的,这一点需要特别注意): 2.在Ma ...