首页 > 代码库 > 洛谷P3166 [CQOI2014]数三角形

洛谷P3166 [CQOI2014]数三角形

题目描述

给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。注意三角形的三点不能共线。

输入输出格式

输入格式:

 

输入一行,包含两个空格分隔的正整数m和n。

 

输出格式:

 

输出一个正整数,为所求三角形数量。

 

输入输出样例

输入样例#1:
2 2
输出样例#1:
76


数据范围
1

——————————————————————————————————————————————————————————————————————————————————

这道题呢不好直接求三角形个数,用全集-补集思想转化为求三点共线的数量。

全部的情况当然是C(n+m,3)然后就处理三点共线问题辣

 

最后枚举所有的斜率然后计算就好辣

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();}
    return ans*f;
}
LL C(LL n,LL m){
    LL ans=1;
    for(int i=n;i>n-m;i--) ans*=i;
    for(int i=m;i;i--) ans/=i;
    return ans;
}
int n,m,f[1007][1007];
int gcd(int a,int b){
    if(f[a][b]) return f[a][b];
    if(!b) return a;
    return f[a][b]=gcd(b,a%b);
}
int main()
{
    n=read()+1; m=read()+1;
    LL sum=C(n*m,3);
    for(int i=-n+1;i<=n-1;i++)
     for(int j=0;j<=m-1;j++){
         if(!j&&i<=0) continue;
         int k=gcd(abs(i),j);
         sum-=(LL)(k-1)*(n-abs(i))*(m-j);
     }printf("%lld\n",sum);
    return 0;
}
View Code

 

 

洛谷P3166 [CQOI2014]数三角形