数三角形acwing(思维+组合数学)

本文解析了一个关于给定网格中不共线三角形计数的问题,通过C++代码展示了如何利用组合数学计算总的可能选择方案并排除共线情况。重点介绍了共线三角形的三种类型及其计算方法。适合理解组合计数和排除法在算法中的应用。
摘要由CSDN通过智能技术生成

给定一个 n×m 的网格,请计算三点都在格点上的三角形共有多少个。

下图为 4×4 的网格上的一个三角形。

a.png
注意:三角形的三点不能共线。
输入格式:
输入一行,包含两个空格分隔的正整数 m 和 n。
输出格式:
输出一个正整数,为所求三角形数量。
题解:首先n+1,m+1,题目给的是网格数,转换为网格点数 ,首先求出C(nm,3),这样就是总共任选三个点的方案数,然后减去共线的方案数就是答案。
共线的分为三种:
1、竖直线上的是m
C(n,3),代表每列任选三个,总共m列
2、水平线上的是nC(m,3),代表每行任选三个,总共n行
3、是倾斜的线段,当然,有斜率大于0的也有斜率小于0的,这两种情况的数量是一样的,只求斜率大于0的就行,斜率大于0的可以枚举构成这条线段的另外两条边来求,比如这条线段可以和底的长度为i,高的长度为j构成一个直角三角形(左下角端点和右上角端点在整点上),这么这俩点之间的整点个数就是gcd(i,j),然后这种三角形的个数总共有(n-i)
(m-j)个,所以答案就是枚举ij,2gcd(i,j)(n-i)*(m-j).
题目:https://www.acwing.com/activity/content/11/可能需要报课才能做

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <stack>
using namespace std;
typedef long long ll;
ll C(int n)
{
    return (ll)n*(n-1)*(n-2)/6;
}
int main()
{
    int n,m;
    cin>>n>>m;
    n++;
    m++;
    ll s=C(n*m)-n*C(m)-m*C(n);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            s-=(ll)2*(__gcd(i,j)-1)*(n-i)*(m-j);
        }
    }
    cout<<s<<endl;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值