2015 浙江省赛C zoj3871 Convex Hull
2015-09-15 18:05
316 查看
<span style="font-family: Arial, Helvetica, Verdana, sans-serif; background-color: rgb(255, 255, 255);"></span>
Edward has n points on the plane. He picks a subset of points (at least three points), and defines the beauty of the subset as twice the area of corresponding convex hull.
Edward wants to know summation of the beauty of all possible subsets of points (at least three points).
No two points coincide and no three points are on the same line.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:The first line contains an integer n (3 ≤ n ≤ 1000). Each of following n lines contains 2 integers xi, yi which
denotes a point (xi, yi) (0 ≤ |xi|, |yi| ≤ 109).
The sum of values n for all the test cases does not exceed 5000.
Output
For each case, if the answer is S, output a single integer denotes S modulo 998244353.Sample Input
1 3 0 0 0 1 1 0
Sample Output
1题意:给定一个点数集合,问所有子集的凸包的面积和的两倍。
做法:关于凸包面积的一种经典算法就是求每条边到原点的有向面积和。这里就可以直接枚举每条边作为凸包上的边,求有向面积乘以出现次数即可。
#include<iostream> #include<cmath> #include<algorithm> #include<cstdio> using namespace std; #define maxn 1001 #define LL long long #define MOD 998244353 struct node{ LL x,y; double ang; node(LL a=0,LL b=0):x(a),y(b){} node operator - (node a){return node(x-a.x,y-a.y); } LL operator ^ (node a){return x*a.y-a.x*y; } bool operator < (const node &a)const{ return ang<a.ang; } void in(){scanf("%lld%lld",&x,&y); } void out(){printf("%lld %lld\n",x,y); } }p[maxn*2],s[maxn]; int n; LL ex2[maxn]; double PI =acos(-1.0); void init(){ for(int i=ex2[0]=1;i<maxn;i++) ex2[i]=(ex2[i-1]*2)%MOD; } LL solve(int x){ swap(p[x],p[0]); for(int i=1;i<n;i++) p[i].ang=atan2(p[i].y-p[0].y,p[i].x-p[0].x); sort(p+1,p+n); for(int i=1;i<n;i++){ p[n+i-1]=p[i]; p[n+i-1].ang+=2.0*PI; } LL res=0; for(int i=1,j=1;i<n;i++){ while(p[j].ang<p[i].ang+PI)j++; LL tmp=(ex2[j-i-1]-1)*(((p[0]^p[i])%MOD+MOD)%MOD)%MOD; res=(res+tmp)%MOD; } return res%MOD; } int main(){ init(); int T;scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++){ p[i].in(); s[i]=p[i]; } LL ans=0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++) p[j]=s[j]; ans=(ans+solve(i))%MOD; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- yum源配置
- java异常的异常类型
- 页面Loading js插件
- Yii上传文件头像详解(二)
- oracle索引
- 美国签证申请中的行政审查制度(图)
- HTML实现思想:
- Java编程思想:第8章 多态
- Ubuntu 命令小记
- hihoCoder 1039 字符消除
- eclipse 中直接打开class文件设置
- ReentrantLock学习笔记
- hihoCoder 1039 字符消除
- 一篇详细的 Android onTouch事件传递机制
- 安卓学习之路之Fragment和Activity之间的传值
- 1007--反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- FFmpeg与SDL双剑合璧之Windows
- 视频黑场检测算法
- Apache Thrift 介绍与开发
- 不需要ViewInject,简化你的findViewById