问题 A: ConvexScore

问题 A: ConvexScore

时间限制: 1 Sec  内存限制: 128 MB
提交: 81  解决: 38
[提交] [状态] [讨论版] [命题人: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个点的所有子集中能围成的凸多边形的贡献值的和,每个凸多边形的贡献值是 2^(凸多边形内包含的点的个数, 不包括边界)。

分析:

经过观察我们可以发现,每个凸多边形的贡献值,就是固定选构成凸多边形的点, 然后任意选凸多边形内的点,所构成的多边形(不存在凸多边形,这个很容易发现)的个数。 所以最终我们就只求一下这n个点一共能够构成多少个多边形就ok了。 暴力枚举就行了,用总的情况 - 不能构成多边行的情况(直线、单个点、空集)

代码稍有改动

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
int n,p[233];
int x[233],y[233];
ll ans;
void init(){
    p[0]=1;
    for(int i=1;i<=n;i++)
        p[i] = (p[i-1]*2)%mod;
}
int main()
{
    init();
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d%d",&x[i],&y[i]);
    ans = p[n]-n-1;
    for(int i=0;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[j])*(y[i]-y[k]) == (x[i]-x[k])*(y[i]-y[j]))
                    cnt++;
            ans = ( ans + mod - p[cnt]) % mod;
        }
    }
    printf("%lld\n",ans%mod);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Du_Mingm/article/details/81381340