原文链接http://www.cnblogs.com/zhouzhendong/p/8934254.html
题目传送门 - ARC082 E
题意
给定二维平面上的$n$个点,定义全集为那$n$个点,求所有满足条件的子集的$Score$和。
条件:要求子集中的点能构成凸多边形。
$Score$的定义:记子集大小为$|s|$,记子集中的点围成的凸多边形中的点的个数(包括端点和边界)为$n$,则$score=2^{n-|s|}$。
答案对于$998244353$取模。
$nleq 200,0leq x_i,y_i<10000$。
题解
插曲:一开始总想DP,后来看了题解才恍然大悟。
题意等价于让你求可以构成凸包的点集个数。
所以,只需要对共线的点集个数进行计数即可。
记得删掉单点的和没点的情况。
代码
#include <bits/stdc++.h> using namespace std; const int N=205,mod=998244353; int n,x[N],y[N],Pow[N]; int main(){ scanf("%d",&n); Pow[0]=1; for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),Pow[i]=Pow[i-1]*2%mod; int ans=(Pow[n]-n-1+mod)%mod; for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++){ int cnt=0; for (int k=j+1;k<=n;k++) if ((x[i]-x[k])*(y[j]-y[k])==(x[j]-x[k])*(y[i]-y[k])) cnt++; ans=(ans-Pow[cnt]+mod)%mod; } printf("%d",ans); return 0; }