当给定网格大小N×M时,我必须解决一个问题,我必须找到“可以放入其中”的平行四边形的数量,以便它们的每个坐标是一个整数。NxM网格上的平行四边形的数量
这里是我的代码:
/*
~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个可能的平行四边形。
我的算法的工作原理和它是正确的,但我需要使它更快一点。我想知道它怎么可能。
P.S.我听说我应该预处理最大公约数并将其保存在一个数组中,这会将运行时间减少到O(n * m),但我不确定如何在不使用cmmdc的情况下执行此操作(最大公约数)功能。
嗨。我很确定你的计算机科学老师只是问你这个问题,让你找出这个问题有多难。接下来你可能会学到的是基于格问题的密码学(又名下一个大事,那个量子计算机还不能打破:-) –
这不是我的计算机科学老师问我的东西,我可能有十倍比我的计算机科学老师更多的知识。这只是我准备在我的国家算法olymics。 – user3220503