ConvexScore

题目地址http://exam.upc.edu.cn/problem.php?cid=1391&pid=0

题意:给N个点,有N的一个子集s组成的一个凸多边形,对于该凸多边形,它的边上是由s个点连接而成,

它的边上和内部共n个点,N中每个子集组成的凸多边形的贡献即是:2的n−|S|次幂。问对于这N个点来

说所有能组成凸多边形的子集的贡献和是多少。结果模除998244353。

参考了别的题解而来

分析:对于一个子集组成的凸多边形,n-s即是内部的点的个数,因此2的(n-s)次幂,即是表示凸多边形

内部的点取(为1)或者不取(为0)两种情况,因为它边上的n个点的个数是固定不变的,所以问题就转化为

对于一个子集n,其固定s个点和其内部的点一共可以组成多少个凸多边形,对于这N个点来说,问题就是可

以形成多少个凸多边形。 比起查找可以形成多少个凸多边形,更简单的是可以用总的情况数减去不满足的个数。

不满足的情况有:全部不取的----1

                            只取一个的-----n

                           只取两个的-----n*(n-1)/2

                            共线的

共线的求法就是枚举:

       枚举两个顶点,看有多少个点在这两个顶点连成的线上。枚举的两个点固定,其他所有点遍历,情况数就是这条线上共线的点集个数。显然,不会有重复。累和,即为最终答案。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define mod 998244353
ll x[100010], y[100010], maze[100010];
int main() {
    ll n;
    
    scanf("%lld", &n);
    for (int i = 0; i<n; ++i) 
		scanf("%lld%lld",&x[i],&y[i]);
		
    maze[0] = 1;
    for (int i = 1; i <= n; ++i) 
		maze[i]=(maze[i-1]*2)%mod;
		
    ll sum= maze[n] - 1 - n - n*(n-1)/2;
    
    for (int i = 0; i < n; i++){
        for (int j = i+1; j < n; j++) {
            int countt = 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])) 
					countt++;
            }
            sum=(sum-(maze[countt]-1)+mod)%mod;
        }
    }
    printf("%lld\n", sum);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值