zoukankan      html  css  js  c++  java
  • How I Mathematician Wonder What You Are!(poj 3130)

    题意:求问多边形的核(能够看到所有点的点)是否存在。

    /*
      对于这样的题目,我只能面向std编程了,然而还是不理解。 
      算法可参考:http://www.cnblogs.com/huangxf/p/4067763.html 
    */
    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #define N 110
    using namespace std;
    int m;
    double r;
    int cCnt,curCnt;////此时cCnt为最终切割得到的多边形的顶点数、暂存顶点个数
    struct point{
        double x,y;
    };
    //读入的多边形的顶点(顺时针)、p为存放最终切割得到的多边形顶点的数组、暂存核的顶点
    point points[N],p[N],q[N];
    void getline(point x,point y,double &a,double &b,double   &c){//两点x、y确定一条直线a、b、c为其系数  
        a=y.y-x.y;  
        b=x.x-y.x;  
        c=y.x*x.y-x.x*y.y;  
    }
    void initial(){
        for(int i=1;i<=m;i++) p[i]=points[i];
        p[m+1]=p[1];
        p[0]=p[m];
        cCnt=m;//cCnt为最终切割得到的多边形的顶点数,将其初始化为多边形的顶点的个数
    }
    point intersect(point x,point y,double a,double b,double c){
        double u=fabs(a*x.x+b*x.y+c);
        double v=fabs(a*y.x+b*y.y+c);
        point pt;
        pt.x=(x.x * v + y.x * u) / (u + v);  
        pt.y=(x.y * v + y.y * u) / (u + v);  
        return  pt;
    }
    void cut(double a,double b,double c){
        curCnt=0;
        for(int i=1;i<=cCnt;i++){
            if(a*p[i].x+b*p[i].y+c>=0) q[++curCnt]=p[i];
            // c由于精度问题,可能会偏小,所以有些点本应在右侧而没在,故应该接着判断
            else {
                if(a*p[i-1].x+b*p[i-1].y+c>0){
                    //如果p[i-1]在直线的右侧的话,则将p[i],p[i-1]形成的直线与已知直线的交点作为核的一个顶点
                    //(这样的话,由于精度的问题,核的面积可能会有所减少)  
                    q[++curCnt]=intersect(p[i],p[i-1],a,b,c);
                }
                if(a*p[i+1].x+b*p[i+1].y+c>0){
                    q[++curCnt]=intersect(p[i],p[i+1],a,b,c);
                }
            }
        }
        for(int i=1;i<=curCnt;i++) p[i]=q[i];//将q中暂存的核的顶点转移到p中
        p[curCnt+1]=q[1];p[0]=p[curCnt];
        cCnt=curCnt;
    }
    void solve(){
        //注意:默认点是顺时针,如果题目不是顺时针,规整化方向
        initial();
        for(int i=1;i<=m;i++){
            double a,b,c;
            getline(points[i],points[i+1],a,b,c);
            cut(a,b,c);
        }
    }
    void guizhenghua(){
        //规整化方向,逆时针变顺时针,顺时针变逆时针
        for(int i=1;i<=m;i++) q[i]=points[m-i+1];
        for(int i=1;i<=m;i++) points[i]=q[i];
    }
    int main(){
        int t;
        while(cin>>m){
            if(m==0) break;
            for(int i=1;i<=m;i++)
                scanf("%lf%lf",&points[i].x,&points[i].y);
            guizhenghua();
            points[m+1]=points[1];
            solve();
            if(cCnt<1) printf("0
    ");
            else printf("1
    ");
        }
        return 0;
    }
  • 相关阅读:
    myeclipse关掉references
    eclipse/myeclipse SVN资源库URL中文乱码问题解决办法
    获取登录用户ip
    MySQL高级 之 explain执行计划详解(转)
    代码部署工具walle(一)
    mongodb备份策略
    nginx报错整理
    记一次java程序占用cpu超高排查
    HDFS恢复误删操作的方法
    有趣的工具
  • 原文地址:https://www.cnblogs.com/harden/p/6285984.html
Copyright © 2011-2022 走看看