这个 an + bnlog2(n) + cn3 = k,在这里为更大的输入找到 n 不能正常工作

This an + bnlog2(n) + cn3 = k, finding n here for bigger input is not working properly

我必须在考试中解决问题。但它无法通过所有测试用例。就是这个等式。

an + bnlog2(n) + cn3 = k 其中给定了 a,b,c,k。该位置最大为 2^63 -1

假设输入是

input:

2 1 1 12167000368000

2 1 1 188000000000000

output:

23000

0

这是我的解决方案

#include<stdio.h>

long long Log2n(long long n)
{
     return (n > 1)? 1 + Log2n(n/2): 0;
 }

int main(){
  long long a,b,c,k, pos, flag = 0;
   scanf("%lld%lld%lld%lld",&a,&b,&c,&k);
   for(int i=0; i<100000000; i++){
        pos = a*i + b*i*Log2n(i)+ c*(i*i*i);
          if(pos == k){
             printf("%lld ",i);
               flag = 1;
                break;
              }
         }
    if(flag == 0){
      printf("0");
    }
  return 0;
 }

像小输入 2 1 1 36 它给出了正确的输入。但是当 k 的输入很大或者数字不是这个时,它就不能正常工作。

我认为我的迭代有问题。这个迭代应该进行多少次?还是有更好的解决方案来找到这个 n 值?

由于 i 声明为 int(i*i*i) 将溢出并调用未定义的行为。

您应该在 pos 的计算中将 i 声明为 long long 或将 i 转换为 long long

 for(int i=0; i<100000000; i++)

应该是

 for(long long i=0; i<100000000; i++)

限制 100000000 似乎有点武断,应该进行调整,因为即使 long long 也可能会溢出。

long long的更改当然不是通用的解决方案,但适用于测试用例。应该大量使用的类型取决于输入变量的域。

请注意 a*i + b*i*Log2n(i)+ c*i*i*i(a + b*Log2n(i)+ c*i*i) * i 基本相同。

这意味着(为了减少溢出的风险)你可以这样做:

    if(k % i == 0) {
        pos_divi = a + b*Log2n(i)+ c*i*i;
        if(pos_divi == k / i) {
             printf("%lld ",i);
             flag = 1;
             break;
        }
    }

我想 k > 0

我们搜索 n^3(a/n^2 + b log2(n)/n^2 + c)= k

需要根据c> 0c = 0c <0

处理几种情况

我离开案例 c = 0,我们将通过 nlog2(n)

进行因式分解

假设c>0。作为 lim |a/n^2| = 0 (n-> +oo) 和 lim |b log2(n)/n^2| = 0 (n-> +oo) 存在 p,例如 n>p|a/n^2| < c/4|b log2(n)/n^2| < c/4

我们可以通过编程方式搜索这样的整数 p

所以 -c/4 < a/n^2 < c/4-c/4 < blog2(n)/n^2 < c/4

因此 n>pn^3*c/2 <= k <= n^3*3*c/2 然后 2k/(3c) <= n^3 <= 2k / c

这简化了对 n ...

的搜索

如果 c < 0 我们可以通过递增 n 并将左侧成员与 k 进行比较并在该成员变为负数时停止来进行循环。