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\n",ans);
return 0;
}