ConvexScore

6603: ConvexScore

时间限制: 1 Sec  内存限制: 128 MB
提交: 47  解决: 21
[提交] [状态] [讨论版] [命题人:admin]

题目描述

You are given N points (xi,yi) located on a two-dimensional plane. Consider a subset S of the N points that forms a convex polygon. Here, we say a set of points S forms a convex polygon when there exists a convex polygon with a positive area that has the same set of vertices as S. All the interior angles of the polygon must be strictly less than 180°.

For example, in the figure above, {A,C,E} and {B,D,E} form convex polygons; {A,C,D,E}, {A,B,C,E}, {A,B,C}, {D,E} and {} do not.
For a given set S, let n be the number of the points among the N points that are inside the convex hull of S (including the boundary and vertices). Then, we will define the score of S as 2n−|S|.
Compute the scores of all possible sets S that form convex polygons, and find the sum of all those scores.
However, since the sum can be extremely large, print the sum modulo 998244353.

Constraints
1≤N≤200
0≤xi,yi<104(1≤i≤N)
If i≠j, xi≠xj or yi≠yj.
xi and yi are integers.

 

输入

The input is given from Standard Input in the following format:
N
x1 y1
x2 y2
:
xN yN

 

输出

Print the sum of all the scores modulo 998244353.

 

样例输入

4
0 0
0 1
1 0
1 1

 

样例输出

5

 

提示

We have five possible sets as S, four sets that form triangles and one set that forms a square. Each of them has a score of 20=1, so the answer is 5.

问题:给定 N 个点,对于一个凸 n 边形,称其的 n 个顶点构成一个集合 S,并且这个多边形内及其边上有 k 个顶点,定义这个 S 的 score 为 2^(k−n).对所有的 score 求和,输出 mod 998244353 的值。

分析:首先看到这个 2^(k−n)这就是在求一个凸多边形内部的点选几个的问题。对于给定的 m 个点,其最外面的一圈轮廓(…)是确定下来的,而顶点的 n 个点也随之确定。所以 就转化为有多少个子集能组成凸多边形。每个点选与不选,就有2^n,减去选一个点的情况n,减去一个都不选的情况1,再减去选两个点的情况,暴力枚举多点共线的情况。两层for固定两个点枚举第三个点。

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=998244353;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );

int n,p[205];
int x[205],y[205];
ll ans;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);
    p[0]=1;
    for(int i=1;i<=n;i++)
        p[i]=(p[i-1]<<1)%mod;

    ans=p[n]-n-1-n*(n-1)/2;

    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            int cut=0;
            for(int k=j+1;k<n;k++)
            {
                if((x[j]-x[i])*(y[k]-y[j])==(x[k]-x[j])*(y[j]-y[i]))
                    cut++;
            }
            ans-=p[cut]-1;
            ans+=mod;
            ans%=mod;
        }
    }
    printf("%lld\n",ans%mod);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值