CSU 1778 多边形的公共部分(计算几何)

博客围绕判断两个简单多边形是否有面积非空的公共部分展开。介绍了简单多边形的定义,给出输入输出格式及示例,还提及判断点在多边形内的思路,并给出AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定两个简单多边形,你的任务是判断二者是否有面积非空的公共部分。如下图中的两个

矩形只有一条公共线段,没有公共面积。

在本题中,简单多边形是指不自交(也不会接触自身)、不含重复顶点并且相邻边不共线的多 边形。

注意:本题并不复杂,但有很多看上去正确的算法实际上暗藏缺陷,请仔细考虑各种情况。

Input
输入包含不超过 100 组数据。每组数据包含两行,每个多边形占一行。多边形的格式是:第一 个整数 n 表示顶点的个数 (3<=n<=100),接下来是 n 对整数(x,y) (-1000<=x,y<=1000),即多边 形的各个顶点,按照逆时针顺序排列。

Output
对于每组数据,如果有非空的公共部分,输出"Yes",否则输出"No"。

Sample Input
4 0 0 2 0 2 2 0 2
4 2 0 4 0 4 2 2 2
4 0 0 2 0 2 2 0 2
4 1 0 3 0 3 2 1 2
Sample Output
Case 1: No
Case 2: Yes

思路:
判断点在多边形内

AC代码:

#include<bits/stdc++.h>
#define LL long long
#define Max 105
const LL mod=1e9+7;
const double PI=acos(-1);
using namespace std;
struct node{
    int x,y;
}a[Max],b[Max];
double Compute(double x1,double y1,double x2,double y2){//算出弧度
    double fz=x1*x2+y1*y2;
    double fm=sqrt(x1*x1+y1*y1)*sqrt(x2*x2+y2*y2);
    return acos(fz/fm);
}
bool judge(node a[],int len,int x,int y){
    double angle=0;
    for(int i=0;i<len;++i){
        int j=(i+1)%len;
        double x1=a[i].x-x;
        double y1=a[i].y-y;
        double x2=a[j].x-x;
        double y2=a[j].y-y;
        angle+=Compute(x1,y1,x2,y2);
    }
    return fabs(angle-2*PI)<1e-6;//和为2Π就在多边形内
}
int main()
{
    int n,m;
    int t=0;
    while(scanf("%d",&n)==1){
        t++;
        for(int i=0;i<n;i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            scanf("%d%d",&b[i].x,&b[i].y);
        bool flag=false;
        for(int i=0;i<n;i++){
            flag=judge(b,m,a[i].x,a[i].y);
            if(flag)
                break;
        }
        if(!flag){
            for(int i=0;i<m;i++){
                flag=judge(a,n,b[i].x,b[i].y);
                if(flag)
                    break;
            }
        }
        printf(!flag?"Case %d: No\n":"Case %d: Yes\n",t);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值