[ICPC 2024 Kunming I] 意大利美食题解

题目描述

堡堡为您准备了一份披萨!这个披萨是一个凸多边形,每条饼边里都有芝士夹心。但这些夹心边很脆弱,导致切披萨的时候只能经过多边形的顶点,而不能从边的中间切开。不幸的是,披萨上有一片您肯定不喜欢的,巨大的圆形菠萝片。

求沿着直线切一刀之后,可以获得的最大的没有菠萝的披萨的面积。称一块披萨上没有菠萝,当且仅当菠萝没有任何部分严格位于披萨块内。也就是说,菠萝和披萨的相交面积为 0。

输入格式

有多个测试数据。第一行输入一个整数 T 表示测试数据组数。对于每组测试数据:

第一行输入一个整数 n(3≤n≤105)表示披萨的顶点数。

第二行输入三个整数 xc​,yc​ 和 r(−109≤xc​,yc​≤109,1≤r≤109)表示菠萝的中心坐标和半径。

对于接下来的 n 行,第 i 行输入两个整数 xi​ 和 yi​(−109≤xi​,yi​≤109)表示第 i 个顶点的坐标。顶点按逆时针顺序列出。保证任意两点不重合。但可能有三个点在同一直线上。

保证菠萝的任何部分都不会超出披萨的边界。另外保证所有数据 n 之和不超过 105。

输出格式

每组测试数据输出一行一个整数,表示最大的没有菠萝的披萨的面积乘以 2。可以证明这个值始终是一个整数。如果无法切出没有菠萝的披萨块,输出 0。

输入输出样例

输入 #1复制

3
5
1 1 1
0 0
1 0
5 0
3 3
0 5
6
2 4 1
2 0
4 0
6 3
4 6
2 6
0 3
4
3 3 1
3 0
6 3
3 6
0 3

输出 #1复制

5
24
0

说明/提示

样例数据如下图所示。

思路

用向量即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long t,n,x,y,r,rr=0,lk=0,kl=0;
struct one{
    long long x,y;
}a[200005];
long long abc2(one xx,one yy,one zz){
	return abs((yy.y-xx.y)*(zz.x-xx.x)+(xx.y-zz.y)*(yy.x-xx.x));
}
bool abc3(one s1,one s2,one l1,one l2){
	long long t1=(l2.y-l1.y)*(s1.x-l1.x)-(l2.x-l1.x)*(s1.y-l1.y);
	long long t2=(l2.y-l1.y)*(s2.x-l1.x)-(l2.x-l1.x)*(s2.y-l1.y);
	if((t1>=0&&t2<=0)||(t1<=0&&t2>=0)){
        return 1;
    }
	return 0;
}
bool abc(one xx,one yy,one zz){
	__int128 ef,cz,ed;
	ef=xx.y-zz.y;
	cz=-(xx.x-zz.x);
	ed=-cz*xx.y-ef*xx.x;
	__int128 dd=(ef*x+cz*y+ed),rr2=r;
	if(dd*dd<rr2*rr2*(ef*ef+cz*cz)) return 0;
	if(abc3(yy,zz,xx,{x,y})==1) return 0;
	else return 1;
}
int main(){
	cin>>t;
	while(t--){
		cin>>n;
        cin>>x>>y>>r;
        for(int i=1;i<=n;i++){
            cin>>a[i].x>>a[i].y;
            a[i+n]=a[i];
        }
        rr=1;
        lk=0;
        kl=0;
        for(int i=1;i<=n;i++){
            while(rr+1<=2*n){
                if(rr<=i){
                    rr++;
                }
                else if(abc(a[i],a[rr],a[rr+1])==1){
                    lk+=abc2(a[i],a[rr],a[rr+1]);
                    rr++;
                }
                else{
                    break;
                }
            }
            kl=max(kl,lk);
            lk-=abc2(a[i],a[i+1],a[rr]);
        }
        cout<<kl<<endl;
	}
	return 0;
}

posted @ 2025-10-21 21:14  bz02_2023f2  阅读(15)  评论(0)    收藏  举报  来源