您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: