当给定网格大小 N x M 时,我必须解决一个问题,我必须找到“可以放入其中”的平行四边形的数量,这样它们的每个坐标都是整数。
这是我的代码:
/*
~Keep It Simple!~
*/
#include<fstream>
#define MaxN 2005
int N,M;
long long Paras[MaxN][MaxN]; // Number of parallelograms of Height i and Width j
long long Rects; // Final Number of Parallelograms
int cmmdc(int a,int b)
{
while(b)
{
int aux = b;
b = a -(( a/b ) * b);
a = aux;
}
return a;
}
int main()
{
freopen("paralelograme.in","r",stdin);
freopen("paralelograme.out","w",stdout);
scanf("%d%d",&N,&M);
for(int i=2; i<=N+1; i++)
for(int j=2; j<=M+1; j++)
{
if(!Paras[i][j])
Paras[i][j] = Paras[j][i] = 1LL*(i-2)*(j-2) + i*j - cmmdc(i-1,j-1) -2; // number of parallelograms with all edges on the grid + number of parallelograms with only 2 edges on the grid.
Rects += 1LL*(M-j+2)*(N-i+2) * Paras[j][i]; // each parallelogram can be moved in (M-j+2)(N-i+2) places.
}
printf("%lld", Rects);
}
示例:对于 2x2 网格,我们有 22 个可能的平行四边形。
我的算法有效并且是正确的,但我需要让它更快一点。我想知道这怎么可能。
PS我听说我应该预处理最大公约数并将其保存在一个数组中,这会将运行时间减少到O(n * m),但我不知道如何在不使用cmmdc的情况下做到这一点(最大公约数)函数。