• gym101657 C


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

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

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

    显然要先求凸包。

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

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

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

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

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef double db;
      4 const db eps=1e-6;
      5 const db pi=acos(-1);
      6 int sign(db k){
      7     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
      8 }
      9 int cmp(db k1,db k2){return sign(k1-k2);}
     10 struct point{
     11     db x,y;
     12     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
     13     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
     14     point operator * (db k1) const{return (point){x*k1,y*k1};}
     15     point operator / (db k1) const{return (point){x/k1,y/k1};}
     16     db abs(){return sqrt(x*x+y*y);}
     17     db dis(point k1){return ((*this)-k1).abs();}
     18     point turn90(){ return point{-y,x};}
     19     db getP()const { return sign(y)==1||(sign(y)==0&&sign(x)==-1);}
     20     point unit(){db w=abs(); return point{x/w,y/w};}
     21     db abs2(){return x*x+y*y;}
     22     bool operator < (const point k1) const{
     23         int a=cmp(x,k1.x);
     24         if (a==-1) return 1; else if (a==1) return 0; else return cmp(y,k1.y)==-1;
     25     }
     26 };
     27 db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
     28 db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
     29 db rad(point k1,point k2){ return atan2(cross(k1,k2),dot(k1,k2));}
     30 int compareangle(point k1,point k2){
     31     return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>0);
     32 }
     33 point proj(point k1,point k2,point q){ // q 到直线 k1,k2 的投影
     34     point k=k2-k1; return k1+k*(dot(q-k1,k)/k.abs2());
     35 }
     36 point getLL(point k1,point k2,point k3,point k4){
     37     db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3);
     38     return (k1*w2+k2*w1)/(w1+w2);
     39 }
     40 struct line{
     41     point p[2];
     42     line(point k1,point k2){p[0]=k1;p[1]=k2;}
     43     point &operator[](int k){ return p[k];}
     44     int include(point k){ return sign(cross(p[1]-p[0],k-p[0])>0);}
     45     point dir(){ return p[1]-p[0];}
     46     line push(db eps){//向左手边平移eps
     47         //const db eps=1e-6;
     48         point delta=(p[1]-p[0]).turn90().unit()*eps;
     49         return {p[0]-delta,p[1]-delta};
     50     }
     51 };
     52 point getLL(line k1,line k2){
     53     return getLL(k1[0],k1[1],k2[0],k2[1]);
     54 }
     55 int parallel(line k1,line k2){ return sign(cross(k1.dir(),k2.dir()))==0;}
     56 int sameDir(line k1,line k2){
     57     return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==1;
     58 }
     59 int operator <(line k1,line k2){
     60     if(sameDir(k1,k2))return k2.include(k1[0]);
     61     return compareangle(k1.dir(),k2.dir());
     62 }
     63 int checkpos(line k1,line k2,line k3){ return k3.include(getLL(k1,k2));}
     64 vector<point> convexHull(vector<point>ps){
     65     int n = ps.size();if(n<=1)return ps;
     66     sort(ps.begin(),ps.end());
     67     vector<point> qs(n*2);int k=0;
     68     for(int i=0;i<n;qs[k++]=ps[i++])
     69         while (k>1&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-2])<=0)--k;
     70     for(int i=n-2,t=k;i>=0;qs[k++]=ps[i--])
     71         while (k>t&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-2])<=0)--k;
     72     qs.resize(k-1);
     73     return qs;
     74 }
     75 int t,n;
     76 vector<point> p;point s1,t1,s2,t2;
     77 map<pair<int,int>,int> mp;
     78 db check(int a,int b,int c,int d){
     79     int id1=mp[make_pair(a,b)],id2=mp[make_pair(c,d)];
     80     s1=p[id1],s2=p[id1]+p[a]-p[b];
     81     point t1 = getLL(p[c],p[d],s1,s2);//一个交点
     82     s1 = p[id2],s2=p[id2]+p[c]-p[d];
     83     point t2 = getLL(p[a],p[b],s1,s2);
     84     point bb = getLL(p[a],p[b],p[c],p[d]);
     85     db S = abs(cross(bb-t1,bb-t2));
     86     return S;
     87 }
     88 void init(){
     89     int m = p.size();
     90     for(int i=0;i<m;i++){
     91         db mx = 0;int id=-1;
     92         for(int j=0;j<m;j++){
     93             db tmp = p[j].dis(proj(p[i],p[(i+1)%m],p[j]));
     94             if(cmp(tmp,mx)>0){
     95                 mx=tmp,id=j;
     96             }
     97         }
     98         mp[make_pair(i,(i+1)%m)]=id;
     99     }
    100 }
    101 point tmp;
    102 int main(){
    103     scanf("%d",&t);
    104     for(int cas=1;cas<=t;cas++){
    105         scanf("%d",&n);
    106         for(int i=0;i<n;i++){
    107             scanf("%lf%lf",&tmp.x,&tmp.y);
    108             p.push_back(tmp);
    109         }
    110         p=convexHull(p);
    111         if(p.size()<3){
    112             printf("Swarm %d Parallelogram Area: 0.0000
    ",cas);
    113             continue;
    114         }
    115         init();
    116         db ans = 1e15;
    117         int m = p.size();
    118         for(int i=0;i<m;i++){
    119             for(int j=i+1;j<m;j++) {
    120                 ans = min(ans,check(i, (i + 1) % m, j,(j+1)%m));
    121             }
    122         }
    123         printf("Swarm %d Parallelogram Area: %.4f
    ",cas,ans);
    124         p.clear();mp.clear();
    125     }
    126 }
    127 /**
    128 1
    129 4
    130 0 0
    131 0 1
    132 0 2
    133 0 3
    134  */
    View Code
  • 相关阅读:
    C代码优化的一些方法
    读书笔记之:C++程序设计原理与实践(其他)[+++]
    读书笔记之:C++ Primer Plus(第5版)
    使用SoapFormatter 类序列化
    C# 多线程学习系列
    winform中读取嵌入的xml文件
    使用Web Service上(服务器端访问)
    jquery ajax调用webservice
    ashx文件和HttpHandler
    以Window服务作为wcf的寄主
  • 原文地址:https://www.cnblogs.com/MXang/p/10466927.html
Copyright © 2020-2023  润新知