• ZOJ 3871 Convex Hull(计算几何、凸包)


    题意:给n个点,|x[i]|,|y[i]| <= 1e9。求在所有情况下的子集下(子集点数>=3),凸包的面积和。

    这题主要有几个方面,一个是凸包的面积,可以直接用线段的有向面积和求得,这个当时没想到。还有就是,在180度以内的点数。

    所以实际上是枚举2个点作为某个凸包的一条边,看有多少个这样的凸包。那个2^num - 1是保证除了2个点外至少还需1个点才能构成凸包。

    时间复杂度O(n*n*logn)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    using namespace std;
    
    const double pi = acos(-1.0);
    #define ll long long
    #define maxn 1010
    #define mod 998244353
    int area2(int ax, int ay, int bx, int by){
    	return ((1ll*ax*by%mod-1ll*ay*bx%mod)%mod+mod)%mod;
    }
    struct Pnt{
    	int x,y;
    	double ang;
    	bool operator < (const Pnt &b) const{
    		return ang < b.ang;
    	}
    }vec[maxn<<1];
    int p2[maxn];
    int main(){
    	p2[0]=1;
    	for(int i=1;i<=1000;++i) p2[i] = (p2[i-1]<<1)%mod;
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		int n;
    		scanf("%d",&n);
    		int x[maxn],y[maxn];
    		for(int i=0;i<n;++i){
    			scanf("%d%d",x+i,y+i);
    		}
    		int ans = 0;
    		for(int i=0;i<n;++i){
    			for(int j=0;j<n;++j){
    				vec[j].x = x[j];
    				vec[j].y = y[j];
    				vec[j].ang = atan2(x[j]-x[i],y[j]-y[i]);
    			}
    			vec[i] = vec[n-1];
    			for(int j=0;j<n-1;++j){
    				vec[j+n-1] = vec[j];
    				vec[j+n-1].ang += pi*2;
    			}
    			int nn = n-1+n-1;
    			sort(vec,vec+nn);
    			int l=0,r=0;
    			while(l<n-1){
    				while(r<nn && vec[r].ang - vec[l].ang < pi) r++;
    				int area = area2(x[i],y[i],vec[l].x,vec[l].y);
    				int cnt = (p2[r-l-1]-1+mod)%mod;
    				ans = (ans+1ll*area*cnt%mod)%mod;
    				++l;
    			}
    		}
    		printf("%d
    ",(mod-ans)%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    土豆网自动播放代码
    js倒计时小插件(兼容大部分浏览器)
    带按钮的网页播放器代码(附文件)
    列出目录下所有文件
    day19 进度条 & 随机验证码
    day18 json与pickle
    day14.2_三元表达式、列表生成式
    day14.1_生成器
    day13_迭代器
    day12.2_完善装饰器
  • 原文地址:https://www.cnblogs.com/nextbin/p/4466912.html
Copyright © 2020-2023  润新知