加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

ZOJ 3871 Convex Hull(计数)

发布时间:2020-12-13 20:09:16 所属栏目:PHP教程 来源:网络整理
导读:1个n边形的面积,可以3角剖分成n 个每一个边和原点构成的3角形的有向面积 这样每条边等于1个有向面积,那末问题转化成只要求每条边能作为几个凸包的边 那末枚举1点O,这样对任意1点X会有1条OX的边,而这条边构成凸包的数量,明显就是只能在和他夹角180度之内

1个n边形的面积,可以3角剖分成n 个每一个边和原点构成的3角形的有向面积

这样每条边等于1个有向面积,那末问题转化成只要求每条边能作为几个凸包的边

那末枚举1点O,这样对任意1点X会有1条OX的边,而这条边构成凸包的数量,明显就是只能在和他夹角180度之内的边之内找,也就是有多少个点,就是2^num - 1(由于最少要有1个点)

因而进行极角排序,双指针扫1遍就可以得到所有答案

代码:

#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; const int MOD = 998244353; const int N = 1005; const double pi = acos(⑴.0); struct Point { int x,y; double ang; void read() { scanf("%d%d",&x,&y); } }; bool cmp(Point a,Point b) { return a.ang < b.ang; } int t,n; Point p[N],tmp[N * 2]; int pow2[N]; int area(Point a,Point b) { return (((ll)a.x * b.y % MOD - (ll)a.y * b.x % MOD ) % MOD + MOD) % MOD;; } int main() { scanf("%d",&t); pow2[0] = 1; for (int i = 1; i < N; i++) pow2[i] = pow2[i - 1] * 2 % MOD; while (t--) { int ans = 0; scanf("%d",&n); for (int i = 0; i < n; i++) p[i].read(); for (int i = 0; i < n; i++) { int tn = 0; for (int j = 0; j < n; j++) { if (i == j) continue; tmp[tn] = p[j]; tmp[tn++].ang = atan2(p[j].y - p[i].y,p[j].x - p[i].x); } for (int j = 0; j < tn; j++) { tmp[j + tn] = tmp[j]; tmp[j + tn].ang += pi * 2; } sort(tmp,tmp + tn * 2,cmp); int r = 0; for (int l = 0; l < tn; l++) { while (tmp[r + 1].ang - tmp[l].ang < pi) r++; ans = (ans + (ll)area(p[i],tmp[l]) * ((pow2[r - l] - 1 + MOD) % MOD) % MOD) % MOD; } } printf("%d ",ans); } return 0; }


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读