AtCoder ARC 082E

传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c

本题是一个平面几何问题。

在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n}。考虑以U的子集S中的点为顶点围成的凸多边形P,若这个凸多边形P内(含边界)的点数为k,则这个子集S的权值为f(S)=2k-|S|。求所有子集S的权值之和$sum_{Ssubseteq U}f(S)$(对998,244,353取余)。

定义一个点集上的凸包运算H:GS。即:平面上的一个点集G,有凸包S=H(G)。

设凸多边形P内的点(除顶点外)构成的集合为T,则|T|=k-|S|。于是,f(S)=2|T|,即f(S)为T的子集个数。设T’是T的一个子集,则:由于集合S=H(ST’),即SST’的凸包,故集合ST’对f(S)的贡献为1。

于是,对于U的一个子集G,若凸多边形P的顶点集为H(G),则集合Gans的贡献为1。因此,在不考虑多点共线的前提下,$ans=card{G|Gsubseteq U,Gge 3}=2^n -(C_{n}^{2}+n+1)$。

若考虑多点共线的情形,则枚举之。设1≤j<i≤n,记L(i,j)={Ak|Ak on AiAj,1≤k<j<i≤n},则在G≥2的情形下,凸包面积为0的情况数为$sum_{1ge jge ige n}2^{|L(i,j)|}$。

因此,$ans=card{G|Gsubseteq U,Gge 3}-sum_{1ge jge ige n}2^{|L(i,j)|}$。

参考程序如下:

#include <stdio.h>
#define MAX_N 201
#define MOD 998244353

int x[MAX_N], y[MAX_N], p[MAX_N];

int main(void)
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d%d", &x[i], &y[i]);
    p[0] = 1;
    for (int i = 0; i < n; i++)
        p[i + 1] = (p[i] << 1) % MOD;
    int ans = p[n] - n - 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            int cnt = 0;
            for (int k = 0; k < j; k++) {
                if ((x[i] - x[j]) * (y[i] - y[k]) == (x[i] - x[k]) * (y[i] - y[j]))
                    cnt++;
            }
            ans -= p[cnt];
            ans += MOD;
            ans %= MOD;
        }
    }
    printf("%d
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/siuginhung/p/7750879.html