Description
给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。
注意三角形的三点不能共线。
Input
输入一行,包含两个空格分隔的正整数m和n。
Output
输出一个正整数,为所求三角形数量。
Sample Input
2 2
Sample Output
76
数据范围
1<=m,n<=1000
数据范围
1<=m,n<=1000
题解Here!
此题不好直接求三角形个数,用补集转化思想转化为求三点共线的数量。
具体求法是先求出水平共线数量与竖直共线数量。
用排列组合的知识可知为$C_n^3$与$C_m^3$。
接着处理倾斜的直线。
直接枚举直线起点终点铁定$TLE$。
注意到除去水平与竖直直线后,每一条直线都是有斜率的。
故只需要枚举倾斜直线的倾斜向量,然后便可以使用最大公约数/排列组合的知识解决了。
附代码:
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; int gcd(int x,int y){ if(y==0)return x; return gcd(y,x%y); } long long c(int n){ long long s=1; s=s*(n-2)*(n-1)*n; s/=6; return s; } int main(){ int n,m; long long ans; scanf("%d%d",&n,&m); n++;m++; ans=c(n*m); if(n>=3)ans-=c(n)*m; if(m>=3)ans-=c(m)*n; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ long long s=gcd(i,j)-1; s=s*2*(n-i)*(m-j); ans-=s; } printf("%lld ",ans); return 0; }