zoukankan      html  css  js  c++  java
  • hdu 3685 多边形重心+凸包

    Rotational Painting

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2498    Accepted Submission(s): 702


    Problem Description
    Josh Lyman is a gifted painter. One of his great works is a glass painting. He creates some well-designed lines on one side of a thick and polygonal glass, and renders it by some special dyes. The most fantastic thing is that it can generate different meaningful paintings by rotating the glass. This method of design is called “Rotational Painting (RP)” which is created by Josh himself. 

    You are a fan of Josh and you bought this glass at the astronomical sum of money. Since the glass is thick enough to put erectly on the table, you want to know in total how many ways you can put it so that you can enjoy as many as possible different paintings hiding on the glass. We assume that material of the glass is uniformly distributed. If you can put it erectly and stably in any ways on the table, you can enjoy it. 

    More specifically, if the polygonal glass is like the polygon in Figure 1, you have just two ways to put it on the table, since all the other ways are not stable. However, the glass like the polygon in Figure 2 has three ways to be appreciated. 

    Pay attention to the cases in Figure 3. We consider that those glasses are not stable.
     
    Input
    The input file contains several test cases. The first line of the file contains an integer T representing the number of test cases. 

    For each test case, the first line is an integer n representing the number of lines of the polygon. (3<=n<=50000). Then n lines follow. The ith line contains two real number xi and yi representing a point of the polygon. (xi, yi) to (xi+1, yi+1) represents a edge of the polygon (1<=i<n), and (xn,yn) to (x1, y1) also represents a edge of the polygon. The input data insures that the polygon is not self-crossed.
     
    Output
    For each test case, output a single integer number in a line representing the number of ways to put the polygonal glass stably on the table.
     
    Sample Input
    2 4 0 0 100 0 99 1 1 1 6 0 0 0 10 1 10 1 1 10 1 10 0
     
    Sample Output
    2 3
    Hint
    The sample test cases can be demonstrated by Figure 1 and Figure 2 in Description part.
    题目大意:给一个多边形,问把它放到平面上是稳定状态的(重心在支撑点以内,在支撑点是不稳定的)种数。
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <vector>
      6 #include <algorithm>
      7 using namespace std;
      8 
      9 const double eps=1e-8;
     10 const double Pi=acos(-1.0);
     11 struct Point
     12 {
     13     double x,y;
     14     Point(double x=0,double y=0):x(x),y(y) {}
     15 };
     16 typedef Point Vector;
     17 Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
     18 Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
     19 Vector operator *(Vector A,double p){return Vector(A.x*p,A.y*p);}
     20 Vector operator /(Vector A,double p){return Vector(A.x/p,A.y/p);}
     21 bool operator < (const Point &a,const Point &b)
     22 {
     23     return a.x<b.x||(a.x==b.x&&a.y<b.y);
     24 }
     25 int dcmp(double x)
     26 {
     27     if(fabs(x)<eps) return 0;
     28     else return x<0?-1:1;
     29 }
     30 bool operator == (const Point &a,const Point &b){
     31     return (dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0);
     32 }
     33 double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;}//点积
     34 double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}//叉积
     35 Point GetLineProjection(Point P,Point A,Point B)//P在直线AB上的投影点
     36 {
     37     Vector v=B-A;
     38     return A+v*(Dot(v,P-A)/Dot(v,v));
     39 }
     40 bool OnSegment(Point p,Point a1,Point a2)//点是否在直线上(不包括端点)
     41 {
     42     return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0;
     43 }
     44 Point getcenter(vector<Point> p)//多边形的重心
     45 {
     46     double area=0;
     47     Point c=Point(0,0);
     48     int i,n=p.size();
     49     for(i=1;i<n-1;i++)
     50     {
     51         double temp=Cross(p[i]-p[0],p[i+1]-p[0]);
     52         c.x+=temp*(p[i].x+p[i+1].x+p[0].x)/3.0;
     53         c.y+=temp*(p[i].y+p[i+1].y+p[0].y)/3.0;
     54         area+=temp;
     55     }
     56     c.x/=area;c.y/=area;
     57     return c;
     58 }
     59 vector<Point> ConvexHull(vector<Point>& p)//求凸包
     60 {
     61     sort(p.begin(), p.end());
     62     p.erase(unique(p.begin(), p.end()), p.end());
     63     int i,n = p.size();
     64     int m = 0;
     65     vector<Point> ch(n+1);
     66     for(i = 0; i < n; i++) {
     67         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     68         ch[m++] = p[i];
     69     }
     70     int k = m;
     71     for(i = n-2; i >= 0; i--) {
     72         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     73         ch[m++] = p[i];
     74     }
     75     if(n > 1) m--;
     76     ch.resize(m);
     77     return ch;
     78 }
     79 
     80 void solve(vector<Point> p,Point center)
     81 {
     82     int ans=0,n=p.size();
     83     for(int i=0;i<n;i++)
     84     {
     85         Point t=GetLineProjection(center,p[i],p[(i+1)%n]);
     86         if(OnSegment(t,p[i],p[(i+1)%n])) ans++;
     87     }
     88     printf("%d
    ",ans);
     89 }
     90 
     91 int main()
     92 {
     93     int i,t,n;
     94     double x,y;
     95     vector<Point> p;
     96     scanf("%d",&t);
     97     while(t--)
     98     {
     99         p.clear();
    100         scanf("%d",&n);
    101         for(i=0;i<n;i++)
    102         {
    103             scanf("%lf%lf",&x,&y);p.push_back(Point(x,y));
    104         }
    105         Point center=getcenter(p);
    106         p=ConvexHull(p);
    107         solve(p,center);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    开发笔记
    PHP的重载及魔术方法
    网站飘窗效果
    asp.net 导入Excel记录到数据库中(转载)
    safari打不开该网页 因为网址无效(解决办法)
    使用join()方法 分隔拆分后的数组
    面向新手的Web服务器搭建——IIS的搭建(转载)
    ueditor上传大容量视频报http请求错误的解决方法(转载)
    表格中针对大段说明文字加一个弹出层
    JS禁止右键及禁止选中文本
  • 原文地址:https://www.cnblogs.com/xiong-/p/3922851.html
Copyright © 2011-2022 走看看