写入两个数字表a
和b
,并按升序合并在一起,并删除重复项。现在的问题是,在此 super 表中查找nth
编号要比O(n)
复杂度更好。
Limits
1<=A, B<=1000
1<=N<=1000000000
这是我的意思,但它是
O(n)
,谁能建议更好的复杂度算法?谢谢!#include <iostream>
#include<map>
using namespace std;
long long int min(long long a, long long b){
if(a<b) return a;
else return b;
}
long long int get( long long int a, long long int b, long long int count) {
long long int val = 0,i;
long long int nexta = a;
long long int nextb = b;
for ( i = 0; i < count; i++) {
val = min(nexta, nextb);
nexta = val < nexta ? nexta : (nexta + a);
nextb = val < nextb ? nextb : (nextb + b);
}
return val;
}
int main() {
int t;
cin >> t;
while(t--){
long long int a,b,n;
cin >> a>> b>> n;
cout << get(a,b,n)<< endl;
}
return 0;
}
示例:
A = 3,B = 5
表格A = 3,6,9,12,15,18等
B的表= 5、10、15、20等
合并后:3、5、6、9、10、12、15、15、18、20等
删除重复项:3、5、6、9、10、12、15、18、20等
对于N = 2,超表的第二个元素为5
最佳答案
如果我理解正确,请按照以下方式指定arays A
和B
:
A[i] = a*i
B[i] = b*i
那么您可以通过应用二进制搜索至少获得
O(log N)
解决方案。考虑一些值
x
。它会超出您的n
元素吗?您需要确定x
之前联合序列中有多少个元素。这很容易做到:从A
中有x/a
元素,从B
中有x/b
,但是糟糕-我们计算了两次常见元素。有x/d
公用元素,其中d
是a
和b
的最小公倍数,因此让我们减去x/d
。因此,如果x/a + x/b - x/d>=n
,则x
至少是n
th元素,否则它在之前。现在二进制搜索代码为(伪代码)
l = 0
r = a * n + 1
d = lcm(a,b)
while r-l>1
m = (r+l)/2
cnt = m/a + m/b - m/d
if cnt >= n
r = m
else l = m
your answer is r
甚至
O(1)
解决方案都可用关于c++ - 计算两个数字的超表中的第N个数字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30352036/