Description
给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。
注意三角形的三点不能共线。
Input
输入一行,包含两个空格分隔的正整数m和n。
Output
输出一个正整数,为所求三角形数量。
Sample Input
2 2
Sample Output
76
数据范围
1<=m,n<=1000
题解:先算出所有点的组合数,再减去再同一直线的组合数,值得一提的是,在同一斜线上的组合数有点复杂。
以(x1, y1) ( x2, y2 )为两端点的线段上有
gcd( y2-y1, x2-x1)-1
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
LL ans, M, N, tot;
LL C( int m, int n ){
LL ret = 1;
for ( int i = m-n+1; i <= m; i++) ret *= i;
for ( int i = 1; i <= n; i++ ) ret /=i;
return ret;
}
LL gcd( LL a, LL b ){
return b==0 ? a : gcd( b, a%b );
}
int main(){
cin >> M >> N, M++, N++;
if ( M > N ) swap( M, N );
tot = M*N;
ans = 0;
ans += C( tot, 3 );
ans -= M *C( N, 3 );
ans -= N *C( M, 3 );
for(LL i=1;i<=N;i++){
for(LL j=1;j<=M;j++){
if(i!=1||j!=1){
if(i==1||j==1) ans-=(gcd(i,j)-1)*(N-i)*(M-j);
else ans-=2*(gcd(i,j)-1)*(N-i)*(M-j);
}
}
}
cout << ans;
}