RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1599123
Accepted
contrlc contrlc
contrlc contrlc
Asked:2024-11-07 20:58:51 +0000 UTC2024-11-07 20:58:51 +0000 UTC 2024-11-07 20:58:51 +0000 UTC

有没有一种不用暴力破解就能解决问题的算法?

  • 772

给出一个自然数n。

想象一下这个数字n是两个整数的和x, y (x, y >= 0),其中没有数字 8 和 9,并且第一项将是可能的最小值。

例如:859 = 102 + 757和849 = 72 + 777。

python
  • 6 6 个回答
  • 218 Views

6 个回答

  • Voted
  1. Андрей NOP
    2024-11-07T22:54:50Z2024-11-07T22:54:50Z

    您肯定需要检查所有数字。

    我们正在寻找左边的第一个8或9,如果你还没有找到,那么a = 0一切就很简单了。

    如果我们找到它,那么我们会进行第一个近似,a这样我们就可以得到这里的所有 7 以及右边到最后的值。

    例子:

    x = ABC8DEF
           ^
    b = ABC7777
    

    此后需要对其进行标准化a。这里我们反其道而行之,向右将所有 8 和 9 增加到 10。

    为什么这已经足够了,并且标准化后a您不必b再次标准化?每个等级的a增幅不会超过2,而b这个等级的y值是7,所以你肯定不会得到8ka或9ka。

    function calc(x) {
      // Множитель для разряда, 100 для x = 849
      let e = Math.pow(10, Math.floor(Math.log10(x)));
      while (e >= 1) {
        const r = x % e;
        const d = (x - r) / e % 10; // Очередная цифра x
        if (d > 7) {
          // Первое приближение a
          // Для x = 849: a = 0 * 100 + 49 + 22 + 1
          let a = (d - 8) * e + r + (e - 1) / 9 * 2 + 1;
          e = 1;
          while (e < a) {
            const r = (a - a % e) / e % 10; // Очередная цифра a
            if (r > 7) {
              a += (10 - r) * e; // Увеличиваем разряд до 10
            }
            e *= 10;
          }
          return a;
        }
        e /= 10;
      }
      return 0;
    }
    
    function print(x) {
      const a = calc(x);
      const b = x - a;
      console.log(x + ' = ' + a + ' + ' + b);
    }
    
    print(100);
    print(777);
    print(849);
    print(859);
    print(868);
    print(890);
    print(899);
    print(900);
    print(985);
    print(993);

    • 5
  2. Best Answer
    Old Skull
    2024-11-08T19:56:06Z2024-11-08T19:56:06Z

    我以前主要用 Delphi 编写代码,所以如果有什么问题我深表歉意......

    1. 我们以数字 859 为例。
    2. 我们计算出最接近它的没有8和9的数字。这个数字是777。
    3. 接下来,我们计算差值:859 - 777 = 82。
    4. 没有 8 和 9 最接近 82 的数字是 100。由于我们从 859 的最后一位数字中减去 2,因此我们需要在 100 上加上 2。我们得到 859 = 102 + 757
    import numpy as np
    
    # find maximal number which is <= num and does not contain 8 and 9
    # ex: 849 => 777; # 178 => 177; # 234 => 234
    def normalize_right_part(num):
        num_arr = np.array(tuple(str(num)))
        m = np.argmax(num_arr > '7')
        if m > 0 or num_arr[0] > '7':
            num_arr[m:] = '7'
        
        return int( ''.join(num_arr) )
    
    # if num does not contains 8 or 9 then leave it as is
    # otherwise round it up to nearest number which does not contain 8 and 9
    # ex: 849 => 1000; # 178 => 200; 234 => 234; 158 => 160
    def normalize_left_part(num):
        num_arr = np.fromiter(str(num), dtype=int)
    
        m = np.argmax(num_arr > 7)
        if m == 0 and num_arr[0] < 8:
            return num
    
        increase = False
    
        for i in range(0, m+1):
            if increase:
                num_arr[m-i] += 1
                increase = False
            
            if num_arr[m-i] > 7:
                num_arr[m-i] = 0
                increase = True
    
        num_arr[m:] = 0
    
        if increase:
            num_arr = np.insert(num_arr, 0, 1)
    
        return int( ''.join(num_arr.astype(dtype=str)) )
    
    # find number = a + b, where a and b don't contain 8 and 9
    # and a is the minimal possible
    def find_sum(num):
        right_part = normalize_right_part(num)
        left_part  = num - right_part
    
        while True:
            left_part = normalize_left_part(left_part)
            right_part = num - left_part
            
            right_part_new = normalize_right_part(right_part)
    
            if right_part_new == right_part:
                break
            
            left_part += right_part - right_part_new
    
        return left_part, right_part
    

    运行tio

    100 = 0 + 100
    107 = 0 + 107
    108 = 1 + 107
    154 = 0 + 154
    777 = 0 + 777
    821 = 44 + 777
    849 = 72 + 777
    853 = 76 + 777
    859 = 102 + 757
    863 = 100 + 763
    867 = 100 + 767
    890 = 113 + 777
    899 = 122 + 777
    900 = 123 + 777
    985 = 210 + 775
    993 = 216 + 777
    880088 = 102311 + 777777
    821000849 = 43223072 + 777777777
    8000000001 = 222222224 + 7777777777
    858585858585 = 101010101010 + 757575757575
    
    • 4
  3. Qwertiy
    2024-11-08T07:41:54Z2024-11-08T07:41:54Z

    一个数字的每一位数字都会变成两个数字之和:max(x-7, 0) + min(x, 7)。没有转移。然后,对于第一个数字中的每个片段10,我们检查是否可以用更小的数字替换这 10,以便在第二个数字的右侧数字中我们得到 7,如果可以,我们将其替换。运行tio

    def solve(x):
      a = []
      b = []
    
      while x:
        d = x % 10
        x //= 10
    
        a.append(max(d-7, 0))
        b.append(min(d, 7))
    
      for i in range(len(a)-1, 1, -1):
        if a[i] == 1 and a[i-1] == 0 and b[i-1] < 5:
          a[i] = 0
          a[i-1] = b[i-1] + 3
          b[i-1] = 7
    
      l = 0
      r = 0
    
      for d in a[::-1]:
        l = l*10 + d
    
      for d in b[::-1]:
        r = r*10 + d
      
      return (l,r)
      
    
    for x in [100, 107, 108, 777, 821, 849, 853, 859, 863, 867, 890, 899, 900, 985, 993, 880088, 821000849, 8000000001]:
      a,b = solve(x)
      print(x, "=", a, "+", b, x == a + b)
    
    100 = 0 + 100 True
    107 = 0 + 107 True
    108 = 1 + 107 True
    777 = 0 + 777 True
    821 = 50 + 771 True
    849 = 72 + 777 True
    853 = 100 + 753 True
    859 = 102 + 757 True
    863 = 100 + 763 True
    867 = 100 + 767 True
    890 = 120 + 770 True
    899 = 122 + 777 True
    900 = 200 + 700 True
    985 = 210 + 775 True
    993 = 220 + 773 True
    880088 = 103011 + 777077 True
    821000849 = 50000072 + 771000777 True
    8000000001 = 300000000 + 7700000001 True
    
    • 3
  4. rotabor
    2024-11-08T06:21:29Z2024-11-08T06:21:29Z

    更新的解决方案:

    def uptake(x):
      sx = str(x)
      br = False
      for i in range(len(sx)):
        if sx[i] > '7':
          br = True
          break
      if br:
        tail = '0' * (len(sx) - i)
        head = ''
        c = '1'
        for j in range(i - 1, -1, -1):
          d = int(sx[j]) + 1
          if d > 7:
            head = '0' + head
          else:
            head = sx[:j] + str(d) + head
            c = ''
            break
        sx = c + head + tail
      return int(sx)
    
    def seven(x):
      sx = str(x)
      for i in range(len(sx)):
        if sx[i] > '7':
          sx = sx[:i] + '7' * (len(sx) - i)
          break
      return int(sx)
        
    def test7(x):
      sx = str(x)
      return '8' in sx or '9' in sx
    
    def p(x):
      y = x - seven(x)
      while test7(y):
        y = x - seven(x - uptake(y))
      print('Result: ', x, y, x - y)
    
    p(100);
    p(107);
    p(108);
    p(777);
    p(849);
    p(853);
    p(859);
    p(863);
    p(890);
    p(899);
    p(900);
    p(985);
    p(993);
    

    结果:100 0 100
    结果:107 0 107
    结果:108 1 107
    结果:777 0 777
    结果:849 72 777
    结果:853 76 777
    结果:859 102 757
    结果:863 100 763
    结果:890 113 777
    结果:899 122 777
    结果:900 123 777
    结果:985 210 775
    结果:993 216 777

    算法:

    1. 吸收给出最接近的较大数字七。
    2. 七给出最接近的较小数字七。
    3. p 寻找摄取和七的收敛。
    • 1
  5. LolPopGames
    2024-11-08T18:48:31Z2024-11-08T18:48:31Z

    首先你需要将数字分成几个数字:

    n = 859 # или другое число
    x = 0 # первое слагаемое
    y = 0 # второе слагаемое
    
    # ------- делим число на цифры
    digits = [] # список для цифр n
    digits.append(n % 10) # первая цифра
    
    # для остальных цифр
    div_a_mod_num = 10
    i=0
    sub_num = digits[0] # число для вычета
    while n > div_a_mod_num/10:
        digits.append((n - sub_num) // div_a_mod_num % div_a_mod_num) # остальные цифры
        i+=1
        div_a_mod_num*=10
        sub_num+=digits[i]
    digits.reverse()
    

    然后你需要找到最大数量:

    # ------- ищем максимальное число
    i=0
    for e in digits:
        digits[i] = e
        if e > 7:
            digits[i] = 7
        i+=1
    

    接下来,将数字转换回数字:

    # ------- превращаем список цифр в число
    digits.reverse()
    i=0
    j=1
    while i < len(digits):
        y += digits[i] * j
        
        i+=1
        j*=10
    

    并计算第一个:

    # ------- вычисляем первое число
    x = n - y
    

    最终代码:

    n = 859 # или другое число
    x = 0 # первое слагаемое
    y = 0 # второе слагаемое
    
    # ------- делим число на цифры
    digits = [] # список для цифр n
    digits.append(n % 10) # первая цифра
    
    # для остальных цифр
    div_a_mod_num = 10
    i=0
    sub_num = digits[0] # число для вычета
    while n > div_a_mod_num/10:
        digits.append((n - sub_num) // div_a_mod_num % div_a_mod_num) # остальные цифры
        i+=1
        div_a_mod_num*=10
        sub_num+=digits[i]
    digits.reverse()
    
    # ------- ищем максимальное число
    i=0
    for e in digits:
        digits[i] = e
        if e > 7:
            digits[i] = 7
        i+=1
    
    # ------- превращаем список цифр в число
    digits.reverse()
    i=0
    j=1
    while i < len(digits):
        y += digits[i] * j
        
        i+=1
        j*=10
    
    # ------- вычисляем первое число
    x = n - y
    
    # ------- показ конечного результата
    print(x, y)
    
    • 1
  6. Leonid
    2024-11-09T17:23:45Z2024-11-09T17:23:45Z

    我将添加一个带字符串的版本。我们正在寻找最大允许数量y。我们找到数字中的n第一个字符8|9,并将从找到的字符到末尾的所有字符替换为7。这就是我们得到的y。

    接下来,我们检查(和 的x差)是否存在 8 或 9。在 中 的相应位置,我们减去 2 或 1。我们不碰数字本身。我们从初始最大值和最终最大值之间的差值获得它。nyyxny

    附言。当然,在 Python 中处理字符串要容易得多)。

    function maxY(n) {
      let strY = String(n);
      let start = strY.search(/8|9/);
      if (start > -1) {
        strY = strY.substring(0, start) + '7'.repeat(strY.length - start);
        let strX = String(n - Number(strY));
        strX.replaceAll(/8|9/g, (mX, posX) => {
          let posY = strY.length - strX.length + posX;
          let numY = +strY[posY] - (mX == '8' ? 2 : 1);
          strY = strY.substring(0, posY) + numY + strY.substring(posY + 1, strY.length);
        });
      }
      return +strY;
    }
    
    function print(n) {
      let y = maxY(n);
      let x = n - y;
    
      console.log(`${n} = ${x} + ${y}`);
    }
    
    print(100);
    print(777);
    print(849);
    print(859);
    print(868);
    print(890);
    print(899);
    print(900);
    print(985);
    print(993);

    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5