找到具有特定数字的最近特定数字(7)

时间:2013-03-02 11:04:16

标签: c++ arrays numbers digit

好吧,我必须编写一个程序来查找给定数字N的NEAREST数字,它具有正好“K”7s。

例如,如果输入为:

N K
1773 3

输出:

1777

哦,还有一件事是N最多可以达到10亿,长期足以处理这个问题吗?

到目前为止,我的代码无效:(

#include <iostream>
using namespace std;
int main()
{
    unsigned long long a, i;
    int b, num=0, dig, tmp;
    cin>>a>>b;
    i=a+1;
    do
    {
        num=0;
        tmp=i;
        while (tmp>0)
        {
            dig=tmp%10;
            tmp=tmp/10;
            if (dig==7)
            num++;
        }
        i++;
    }
    while(num<b);
    cout<<i-1;
    return 0;
}

3 个答案:

答案 0 :(得分:2)

您的问题不是编程问题,而是数学问题。

m = 1+E(log10(N)),即N的十进制写入中的位数(通过计算数字比使用对数计算它可能更快)。

mK7N的数量。

N'为输出数字。

我看到4个案例:

  • K >= m:然后N' = 7..7K位数字。)
  • K == mK:然后N' = N
  • K > mK and K < m:然后从最低有效数字开始用7替换所有非7数字。例如:N = 1 357 975 , K = 4 => N' = 1 357 777。警告:如果您有8,则有一个特殊情况,例如:N = 80, N' = 79。您可以通过使用公共前缀,然后生成全7后缀(特殊情况:从前缀中删除一个并添加7 9 7 7 ... 7)来执行此操作。请参阅代码中的special case
  • K < mK:有两个可能的数字。

    让我们分解NN = a1 a2 ... ap 7 b1 b2 ... bq,其中

    • a1 ... app
    • 中的[0..9]个数字
    • b1 ... bq是[{1}}
    • 中的q个数字

    [0..9] \ {7}A = a1 ... ap 6 9 ... 9之后设B = a1 ... ap 8 0 ... 0q 6位数。然后,8。如果两个数字都相等,那么您可以选择。

抱歉数学格式不正确。 代码现在可以更容易编写。 Here is my implementation

N' = closestToN(A,B)

关于#include <iostream> unsigned long long getClosestWith7(unsigned long long n, unsigned int k) { // Count number of digits unsigned long long tmp = n; unsigned int m = 0, mK = 0; while(tmp > 0) { if(tmp % 10 == 7) mK++; tmp /= 10; m++; } // Distinct cases if(k == mK && n != 0) return n; else if(k >= m || n == 0) // implicit: k != mK { unsigned long long r = 0; while(k > 0) { r = 10 * r + 7; k--; } return r; } else if(k > mK) // implicit: k != mK, k < m { unsigned long long r = n; unsigned long long s = 0; m = 0; while(mK < k) { if(r % 10 != 7) mK++; r /= 10; m++; } if(r % 10 == 8) // special case s = 79 + 100 * (r / 10); while(m > 0) { r = 10 * r + 7; if(s != 0 && m > 1) // special case s = 10 * s + 7; m--; } return (r < n && n - r < n - s) || (r >= n && r - n < n - s) ? r : s; } else // implicit : k < mK { // Generate a and b unsigned long long a = n; unsigned long long b = 0; m = 0; while(mK > k) { if(a % 10 == 7) mK--; a /= 10; m++; } b = 10 * a + 8; a = 10 * a + 6; m--; while(m > 0) { a = 10 * a + 9; b = 10 * b + 0; m--; } // Compare (return lowest if equal) return n - a <= b - n ? a : b; } } #define CLOSEST7( N , K ) \ std::cout << "N = " << N << ", K = " << K << " => N' = " << getClosestWith7(N,K) << "\n" int main() { CLOSEST7(1773,3); CLOSEST7(83,1); CLOSEST7(17273,3); CLOSEST7(1273679750,6); CLOSEST7(1773,1); CLOSEST7(83,5); CLOSEST7(0,2); CLOSEST7(0,0); } 的问题:它取决于编译器。通常,这种类型的大小是64位,因此您可以存储0到2 ^ 64 - 1(无符号)的数字,即18 446 744 073 709 551 615,因此在大多数实现中它应该适用于您的数据范围

答案 1 :(得分:1)

一些问题:

  • ans=i在您将其分成几次后记录一些i,您需要记录原始i
  • 您只需沿1个方向循环,您需要同时检查两个方向
  • 循环所有数字从根本上说太慢了
    • 如果数字是100 000 000 000 000且k = 14,您需要检查22 222 222 222 223(100 000 000 000 000 777 777 777 777)数字,这是不可行的

旁注 - the maximum for long long is 9223372036854775807

以下是一些应该有效的伪代码:

num = number of 7s in input
if (num == k)
  print input
if (num < k)
  a = input with (k-num) non-7 digits from least significant digit set to 7
    let x = last position set
  b = substring(input, 1, position)
  c = b + 1
  d = b - 1
  ba = concat(b, substring(a, position, end))
  ca = concat(c, substring(a, position, end))
  da = concat(d, substring(a, position, end))
  if (abs(input - ba) <= abs(input - ca) &&
      abs(input - ba) <= abs(input - da))
    print b
  else
  if (abs(input - ca) <= abs(input - ba) &&
      abs(input - ca) <= abs(input - da))
    print c
  else
    print d
if (num > k)
  x = (k-num)th 7 from least significant digit
  a = input with x set to 6 and all less significant digits to 9
  b = input with x set to 8 and all less significant digits to 0
  if (input - a > b - input)
    print b
  else
    print a

答案 2 :(得分:0)

这个算法怎么样?

  1. 将数字转换为字符串。

  2. 计算其中的7个数。

  3. 如果它比K少7,则将数字从最右边到左边逐个更改为7s,直到达到K,然后转到步骤5.

  4. 如果它的K比7更多,只有当它们为7时,将数字从最右边的数字逐个更改为6s,直到达到K,然后转到步骤5。

  5. 将其转换回整数。

  6. 根据Dukeling的回答,

    long long是可用的。