zoukankan      html  css  js  c++  java
  • POJ 3130 How I Mathematician Wonder What You Are!(半平面交求多边形的核)

    题目链接

    题意 : 给你一个多边形,问你该多边形中是否存在一个点使得该点与该多边形任意一点的连线都在多边形之内。

    思路 : 与3335一样,不过要注意方向变化一下。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <math.h>
     5 
     6 using namespace std ;
     7 
     8 struct node
     9 {
    10     double x;
    11     double y ;
    12 } p[110],temp[110],newp[110];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
    13 int n,newn ;//原来的点数,切割后的点数
    14 double a,b,c ;//直线方程的三个系数
    15 
    16 void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
    17 {
    18     a = y.y-x.y ;
    19     b = x.x-y.x ;
    20     c = y.x*x.y - y.y*x.x ;
    21 }
    22 node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
    23 {
    24     double u = fabs(a*x.x+b*x.y+c) ;
    25     double v = fabs(a*y.x+b*y.y+c) ;
    26     node t ;
    27     t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
    28     t.y = (x.y*v+y.y*u)/(u+v) ;
    29     return t ;
    30 }
    31 void cut()
    32 {
    33     int cutn = 0 ;
    34     for(int i = 1 ; i <= newn ; i++)
    35     {
    36         if(a*newp[i].x+b*newp[i].y+c >= 0)//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
    37             temp[ ++cutn] = newp[i] ;
    38         else
    39         {
    40             if(a*newp[i-1].x+b*newp[i-1].y+c > 0)
    41                 temp[++cutn ] = intersect(newp[i-1],newp[i]) ;//把新交点加入
    42             if(a*newp[i+1].x+b*newp[i+1].y+c > 0)
    43                 temp[ ++cutn] = intersect(newp[i+1],newp[i]) ;
    44         }
    45     }
    46     for(int i = 1 ; i <= cutn ; i++)
    47         newp[i] = temp[i] ;
    48     newp[cutn+1] = temp[1] ;//能够找出所有点的前驱和后继
    49     newp[0] = temp[cutn] ;
    50     newn = cutn ;
    51 }
    52 
    53 void solve()
    54 {
    55     for(int i = 1 ; i <= n ; i++)
    56     {
    57         newp[i] = p[i] ;
    58     }
    59     p[n+1] = p[1] ;
    60     newp[n+1] = newp[1] ;
    61     newp[0] = newp[n] ;
    62     newn = n ;
    63     for(int i = 1 ; i <= n ; i++)
    64     {
    65         getline(p[i],p[i+1]) ;//从头开始顺序遍历两个相邻点。
    66         cut() ;
    67     }
    68 }
    69 void guizhenghua()
    70 {
    71     for(int i = 1 ; i < (n+1)/2 ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
    72         swap(p[i],p[n-i]) ;
    73 }
    74 int main()
    75 {
    76     while(scanf("%d",&n)!=EOF && n)
    77     {
    78         for(int i = 1 ; i <= n ; i++)
    79             scanf("%lf %lf",&p[i].x,&p[i].y) ;
    80             guizhenghua() ;
    81             p[n+1] = p[1] ;
    82         solve() ;
    83         if(newn == 0) puts("0") ;
    84         else puts("1") ;
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    cmd常用命令大全
    网卡物理地址
    想看密码的请心平气和听我说
    作为一个程序员仪表
    960,950栅格化方法
    为什么要拿宽960做栅格化呢
    960栅格化优势
    虎牌 查询 自选号
    视频
    在线学习视频地址
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3959475.html
Copyright © 2011-2022 走看看