3505: [Cqoi2014]数三角形
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1951 Solved: 1195
[ Submit][ Status][ Discuss]
Description
给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。
注意三角形的三点不能共线。
Input
输入一行,包含两个空格分隔的正整数m和n。
Output
输出一个正整数,为所求三角形数量。
Sample Input
2 2
Sample Output
76
数据范围
1<=m,n<=1000
数据范围
1<=m,n<=1000
【分析】
tot=(n+1)*(m+1);
先计算出所有的选取三点的方案数C( tot , 3 ),再减掉直线上的三角形。
直线上的三角形,可以枚举两点(a,b),(x,y),第三点在两点之间选。
直接令(a,b)=(0,0),枚举(x,y),其他位置可以通过平移得到,乘上平移能得到的数目。
注:当x,y都不为0时,有对称的直线存在,一次要乘两倍,而在边缘时,不存在。(画图可看出)
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int gcd(int a,int b){while(b)b^=a^=b^=a%=b;return a;}
int main()
{
int n,m;
cin>>n>>m;
ll tot=(n+1)*(m+1);
ll ans=tot*(tot-1)*(tot-2)/6;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)if(i||j) //枚举两端点
{
ll res=(gcd(i,j)-1)*(m-j+1)*(n-i+1);
if(i&&j)ans-=res*2;
else ans-=res;
}
}
cout<<ans<<endl;
}