Gao the Grid
Time Limit: 2 Seconds Memory Limit: 65536 KB
A n * m grid as follow:
a n*m grid(n=4,m=3)
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).
a triangle 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
题目大意:给出n,m计算在格顶上的三角形有多少个。
解题关键:先算出C(全部格点数,3)然后减去直线的情况,gcd(i,j) - 1 计算出i,j(直角三角形的两条边)其斜边落在格点上的点数有几个。
题目链接:ZOJ 3647
以下是代码:
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
long long gcd(int a,int b)
{
return b == 0 ? a : gcd(b,a % b);
}
long long com(long long n, long long r){
if (n < r) return 0;
if( n-r < r ) r = n-r;
long long i, j, s = 1;
for( i=0, j=1; i <r; ++i ){
s *= (n-i);
for( ; j <= r&& s%j == 0; ++j ) s /= j;
}
return s;
}
int main(){
int n,m;
while(cin >> n >> m)
{
long long ans = com((n + 1) * (m + 1),3) - com(n + 1,3) * (m + 1) - com (m + 1,3) * (n + 1);
for (int i = 2; i <= n; i++)
{
for (int j = 2; j <= m; j++)
{
ans = ans- (gcd(i,j) - 1) * (n - i + 1) * (m - j + 1) * 2;
}
}
cout << ans << endl;
}
return 0;
}