今天Mayuyu遇到了一道组合问题,题目描述如下。
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4837
题意:给定一个的矩阵,在这个矩阵中任意选取3点,能构成多少个三角形?
分析:这个题明显是一个组合问题,利用容斥的思想。在的矩阵中一共有个点,那么有种
选择,在这种选择中三点共线的情况是不合法的,不合法主要分两种情况。
(1)处于同一斜线上
枚举的矩形,那么对角线上的两点已经固定,在这两点中间选一个点即可,我们知道,给定两个整
数端点和,直线上的整点个数为,减去已经固定的两
个,中间还有个整点,然后的矩形还可以移动,一共有
种情况,而每一个矩形有两个对角线,所以还要乘以2。
(2)处于同一竖直线或者水平线上
这种情况容易一点在每一个竖直线上选择3点,且每一列都是这样共有种情况。
同理,还有。
代码:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef long long LL; LL gcd(LL a,LL b) { return b ? gcd(b,a%b):a; } LL num(LL n,LL m) { LL ans = 0; for(int i=2;i<=n;i++) { for(int j=2;j<=m;j++) ans += (gcd(i,j) - 1) * (n - i + 1) * (m - j + 1) * 2; } return ans; } LL Work(LL n,LL m) { LL t = (n + 1) * (m + 1); LL ans = t * (t - 1) * (t - 2) / 6; ans -= num(n,m); ans -= n * (n * n - 1) * (m + 1) / 6; ans -= m * (m * m - 1) * (n + 1) / 6; return ans; } int main() { LL n,m; while(scanf("%lld%lld",&n,&m)!=EOF) printf("%lld\n",Work(n,m)); return 0; }
一个组合问题
时间: 2024-10-11 05:27:33