Я должен решить проблему, когда задан размер сетки N x 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);
}
Пример: 2х2 сетки есть 22 возможных параллелограммов.
Мой алгоритм работает, и это правильно, но мне нужно сделать это немного быстрее. Я хочу знать, как это возможно.
P.S. Я слышал, что я должен предварительно обработать наибольший общий делитель и сохранить его в массиве, который сократит время выполнения до O (n * m), но я не уверен, как это сделать без использования cmmdc (наибольший общий делитель).
Привет. Я почти уверен, что ваш учитель информатики просто задает вам этот вопрос, чтобы вы могли узнать, насколько сложно этот вопрос. Следующее, что вы, вероятно, узнаете, - это криптография, основанная на проблемах решетки (также следующая важная вещь, которая еще не может быть нарушена квантовыми компьютерами :-) –
Это не мой учитель информатики, спрашивающий меня о вещах, я, вероятно, имею десять раз больше знаний, чем мой учитель информатики. Это только я готовлюсь к алгоритмической олимсике в моей стране. – user3220503