ZOJ-3647 Gao the Grid

来源:互联网 发布:电信网络字母 编辑:程序博客网 时间:2024/05/02 01:26

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;}
0 0