zoukankan      html  css  js  c++  java
  • poj 3335Rotating Scoreboard解题报告

    链接:http://poj.org/problem?id=3335

    半平面交求多边形的核,多边形的核是多边形的一个区域,这个区域内的点与整个多边形内的任意一点的连线整个线段都在多边形内部,即对这个区域内的点来说,多边形内的所有点都是可见的。而半平面是说,一个二维空间被一个直线分为了两部分,确定这两部分可以用ax+by+c>=0或者ax+by+c<0来确定。这个是n^2的算法,但是对这道题已经足够了。

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #define eps 1e-8
      6 #define N 105
      7 using namespace std;
      8 struct point
      9 {
     10     double x,y;
     11 };
     12 point p[N];
     13 point s[N];
     14 point q[N];
     15 int n,size,si;
     16 void init()
     17 {
     18     int i;
     19     for(i=1;i<=n;i++)
     20     p[i]=s[i];
     21     p[n+1]=p[1];
     22     p[0]=p[n];
     23     size=n;
     24 }
     25 int sig(double k)
     26 {
     27     return (k<-eps)?-1:(k>eps);
     28 }
     29 void getl(point p1,point p2,double &a,double &b,double &c)
     30 {
     31     a=p2.y-p1.y;
     32     b=p1.x-p2.x;
     33     c=p2.x*p1.y-p2.y*p1.x;
     34 }
     35 point intersect(point x,point y,double a,double b,double c)
     36 {
     37     double u=fabs(a*x.x+b*x.y+c);
     38     double v=fabs(a*y.x+b*y.y+c);
     39     point temp;
     40     temp.x=(x.x*v+y.x*u)/(u+v);
     41     temp.y=(x.y*v+y.y*u)/(u+v);
     42     return temp;
     43 }
     44 void cut(double a,double b,double c)//对多边形的每一条边进行切割
     45 {
     46     int i;
     47     si=0;
     48     for(i=1;i<=size;i++)//枚举在暂时确定的多边形内,有多少点不在直线的右侧
     49     {
     50         if(sig(a*p[i].x+b*p[i].y+c)>=0)
     51         q[++si]=p[i];
     52         else
     53         {
     54             if(sig(a*p[i-1].x+b*p[i-1].y+c)>0)
     55             q[++si]=intersect(p[i],p[i-1],a,b,c);
     56             if(sig(a*p[i+1].x+b*p[i+1].y+c)>0)
     57             q[++si]=intersect(p[i],p[i+1],a,b,c);
     58         }
     59     }
     60     for(i=1;i<=si;i++)//更新整个多边形的核
     61     p[i]=q[i];
     62     p[0]=p[si];
     63     p[si+1]=p[1];
     64     size=si;
     65     //for(i=1;i<=si;i++)
     66     //printf("%lf %lf\n",p[i].x,p[i].y);
     67     //printf("%lf %lf %lf %d\n",a,b,c,si);
     68 }
     69 bool solve()
     70 {
     71     int i;
     72     double a,b,c;
     73     for(i=1;i<=n;i++)
     74     {
     75         getl(s[i],s[i+1],a,b,c);
     76         cut(a,b,c);
     77     }
     78     //printf("%d\n",size);
     79     if(size)//不存在核
     80     return true;
     81     return false;
     82 }
     83 int main()
     84 {
     85     int t;
     86     scanf("%d",&t);
     87     int i;
     88     while(t--)
     89     {
     90         scanf("%d",&n);
     91         for(i=1;i<=n;i++)
     92         scanf("%lf%lf",&s[i].x,&s[i].y);
     93         s[n+1]=s[1];
     94         s[0]=s[n];
     95         init();
     96         if(solve())
     97         printf("YES\n");
     98         else
     99         printf("NO\n");
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    求C的近似值
    判断是否直角三角形
    温度转换异常处理
    python html页面
    python 爬虫goole主页
    python 足球模拟
    python模拟羽毛球竞技
    python 读书报告
    python 用jieba分词统计关于红楼梦的高频词
    python 在终端输出如下信息
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2488693.html
Copyright © 2011-2022 走看看