prow2012-A3-0005

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

此题求:一个n×m的格点矩形中,三角形数量。 

可得最后答案是C((N+1)*(M+1),3)-共线的三角形个数

枚举这些共线三角形的两个顶点,另一个顶点是在网格上的数量是gcd(x,y)-1,注意需要*2,因为矩形有两条对角线。

{{{

#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <sstream>
#include <string>
#include <math.h>
using namespace std;
typedef long long LL;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    int N,M,x,y,num;
    while(scanf("%d%d",&N,&M)!=EOF){
        LL tot = (N+1)*(M+1);
        tot = (tot*(tot-1)*(tot-2))/6;
        for (x = 0;x<=N;x++)
            for (y=0;y<=M;y++){
                if (x==0||y==0)
                     num = max(x,y)-1;
                else 
                     num = gcd(x,y)-1,num*=2;
            //printf("%d %d :%d\n",x,y,num);
                if (num>0)
                    tot-=1LL*num*((N-x+1)*(M-y+1));
            }
        cout<<tot<<endl;
    }
}

}}}

此题求:一个n×m的格点矩形中,三角形数量。

可得最后答案是C((N+1)*(M+1),3)-共线的三角形个数

枚举这些共线三角形的两个顶点,另一个顶点是在网格上的数量是gcd(x,y)-1,注意需要*2,因为矩形有两条对角线。

#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <sstream>
#include <string>
#include <math.h>
using namespace std;
typedef long long LL;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    int N,M,x,y,num;
    while(scanf("%d%d",&N,&M)!=EOF){
        LL tot = (N+1)*(M+1);
        tot = (tot*(tot-1)*(tot-2))/6;
        for (x = 0;x<=N;x++)
            for (y=0;y<=M;y++){
                if (x==0||y==0)
                     num = max(x,y)-1;
                else 
                     num = gcd(x,y)-1,num*=2;
            //printf("%d %d :%d\n",x,y,num);
                if (num>0)
                    tot-=1LL*num*((N-x+1)*(M-y+1));
            }
        cout<<tot<<endl;
    }
}