A n * m grid as follow:
Count the number of triangles, three of whose vertice must be grid-points.
Note that the three vertice of the triangle must not be in a line(the right picture is not a triangle).
Input
The input consists of several cases. Each case consists of two positive integers n and m (1 ≤ n, m ≤ 1000).
Output
For each case, output the total number of triangle.
Sample Input
1 1 2 2
Sample Output
4 76
hint
hint for 2nd case: C(9, 3) - 8 = 76
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4837
求一个格子图里最多有多少不同的三角形(位置不同也算)
这题要倒着来思考。先求出所有3个点的组合数,再减去其中不符合的(三点共线)——这个地方不容易思考。本来想直接枚举的,但不可行。经过大神指导明白了一个定理:告诉你长和宽,求格子图里与这条线段(斜边)共线的点有多少个:gcd(i,j)-1
然后这条线段可以放的位置有(n+1-i)*(m+1-j)种。因为有同样的对角线(中心对称)所以*2.
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#include <ctime>
#include <cstdlib>
#define ll long long
using namespace std;
long long C(int n,int m)
{
long long res=1;
if(n<m) return 0;
if(n-m<m) m=n-m;
int i,j;
for(i=0,j=1;i<m;i++)
{
res*=(n-i);
for(;j<=m&&res%j==0;j++) res/=j;
}
return res;
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;}
int main(){
ll n,m;
while(cin>>n>>m){
ll s=C((n+1)*(m+1),3)-C(m+1,3)*(n+1)-C(n+1,3)*(m+1);
for(int i=2;i<=n;++i){
for(int j=2;j<=m;++j){
s-=(gcd(i,j)-1)*(n+1-i)*(m+1-j)*2;
}
}
cout<<s<<endl;
}
return 0;
}