Я решаю проблему CS, и мне мало нужна помощь. У меня число N, и мне нужно подсчитать количество различных прямоугольников, в которых диагональ проходит по N квадратам, если прямоугольник разбит на прямоугольники размером 1x1. Эта фотография поможет вам понять.Число четких прямоугольников, в которых диагональ проходит по N квадратам
Эта картина показывает все 4 комбинации, если N = 4, на самом деле прямоугольники, в которых диагонали проходит в 4-х квадратов с размерами 1x4, 2x3, 4x2 и 4x4.
Я нашел формулу, если мы дали два размера прямоугольников оно:
А + В - НОД (А, В)
, так как N < = 10^6, я идти вверх до 10^6 и проверить для каждого N делители N, сложность которого равна O (N sqrt (N)), так как дивизоры A являются gcd (A, B) i решают систему уравнений q является делителем из A и q является gcd (A, B) A + Bq = N и gcd (A, B) = q Я решил это в O (N sqrt (N) * log (N)) , где я предполагаю, что log (N) - это время, чтобы найти gcd двух номера.
Поскольку срок составляет 3 секунды, он не работает вовремя. Мне нужна помощь в оптимизации решения.
Update: Вот мой код:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a;
int gcd(int a, int b) {
if(b>a) swap(a,b);
if(b==0) return a;
return gcd(b, a%b);
}
bool valid(int n, int m, int gc, int a) {
if(n+m-gc==a) return true;
return false;
}
int main() {
cin>>a;
int counter=0;
for(int i=1;i<=a/2;i++) {
for(ll j=1;j<=sqrt(i);j++) {
if(i%j==0) {
if(j!=i/j) {
int m1 = a+j-i;
int div=i/j;
int m2 = a+div-i;
if(valid(i, m1, j, a)) {
if(gcd(i, m1)==j)
counter++;
}
if(valid(i, m2, i/j, a)) {
if(gcd(i,m2)==i/j)
counter++;
}
}
else {
int m1 = a+j-i;
if(valid(i, m1, j, a)) {
if(gcd(i, m1)==j)
counter++;
}
}
}
}
}
cout<<counter+1;
return 0;
}
Спасибо заранее.
Пожалуйста, покажите свой код. –
Я отправил свой код. – someone12321