【问题标题】:how to solve this without a loop?如何在没有循环的情况下解决这个问题?
【发布时间】:2023-02-25 05:58:01
【问题描述】:

我们给定了 3 个数字 y、x 和 n。我们被要求在 1 <= k <= n 和 k % x = y 的情况下找到最大的 k。 例如: 输入:1 2 100 输出:99

我能写的是:

#include <stdio.h>
int main()
{
   int y, x, n, max = 1;
   scanf("%d %d %d", &y, &x, &n);
   for (int k = 1; k <= n; k++)
   {
        if ((k % x == y) && (k >= max))
        max = k;
   }
   printf("%d", max);
   return 0;
}

它完全正确。但问题是应该在不使用任何循环或 if 的情况下编写程序。 任何人有任何想法?

【问题讨论】:

  • 递归函数?
  • 如果只有 3 个数字,您可以使用 if 语句获得。
  • 使用 goto 可以接受吗?
  • Fateme,x, y的可能范围是多少? (当然x==0是个问题。)
  • Fateme,“它完全可以正常工作。” --> 试试x &lt;= y的任何情况。

标签: c loops if-statement division


【解决方案1】:

这个答案假设所有数字都是非负数,x 是非零的,并且 0 ≤ y < x

如果存在,满足条件的最大数是(n-y)/x*x + y

证明:

mx的最大倍数,不大于n-y。然后 n-y = m+r 对于某些 0 ≤ r < x。 (如果r是负数,m将大于n-y。如果是x或更大,m将不是最大的倍数,因为m+x将是x的倍数不大于n-y。)

然后 (n-y)/x = (m+r)/x = m/x 因为整数除法会丢弃余数。所以(n-y)/x*x=m

因为mx的倍数,所以m % x = 0。那么(m+y) % x = y,所以(n-y)/x*x + y = y

要查看这是不大于 n 的最大此类数字,观察下一个更大的数字与 y 的余数是 (n-y)/x*x + y + x = m + y + x = m + y + r + (x-r) = (n-y) + y + (x-r) = n + (x-r),我们知道x-r 是正数,所以它大于n

注意:关于条件 1 ≤ k,如果 n 足够大以允许这样的解决方案,则自动满足此条件,因为公式产生最大的 k ≤ n,其余数模 xy。如果公式得出的k不满足1≤k,则无解。

【讨论】:

    【解决方案2】:

    给定的程序针对给定的 y、x 和 n 值找到满足条件 (k % x == y) 和 (k >= max) 的最大整数 k。这可以通过使用算术级数公式在没有循环的情况下完成。

    满足条件(k % x == y)的最大整数k可以写成k = x * q + y,其中q是一个整数。所以,我们需要找到最大的 q 使得 x * q + y <= n。

    可以使用公式 q = floor((n - y) / x) 找到最大的 q。在这里,floor 是向下舍入到最接近的整数的函数。

    然后,我们可以将 k 计算为 k = x * q + y。如果 k >= max,则 max = k。

    这是没有循环的修改后的代码:

    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
       int y, x, n, max = 1;
       scanf("%d %d %d", &y, &x, &n);
       
       int q = floor((n - y) / (double)x); // compute largest q
       int k = x * q + y; // compute k
       if (k >= max) max = k; // update max if necessary
       
       printf("%d", max);
       return 0;
    }
    

    请注意,我们需要包含 floor 函数的 math.h 头文件。此外,我们需要在除法之前将 x 转换为 double 以确保结果是浮点数。

    【讨论】:

    • 正值 floor((n - y) / (double)x) 可替换为 (n - y) / x。在这个整数问题中不需要浮点数。
    【解决方案3】:

    我正在寻找一个完整的(+ 和 -)x, y 答案,没有 int 溢出,并清楚地确定什么时候没有解决方案是可能的。


    鉴于:

    1 <= k <= n
    k % x == y
    

    k % x == y暗示
    k = quotient * x + y 其中quotient 是某个整数。


    x == 0, 然后
    any_int % 0 未定义,因此在 C 中我们不能确定地形成答案。
    1 &lt;= n 在所有情况下也是必需的。

    if (x == 0 || n < 1) No_solution;
    

    x &gt; 0, 然后
    y &gt;= 0positive_int % x is never &lt; 0)
    y &lt; xpositive_int % x is always &lt; x)。
    使用k % x == y1 &lt;= k &lt;= n,然后
    对于解决方案,n &gt;= y 必须为真。

    if (x > 0 && (y < 0 || y >= x || y > n)) No_solution;
    

    上面拒绝后没有解决方案组合:

    quotient * x + y <= n       // leads to ...
    quotient <= (n-y)/x         // quotient is >= 0 and overflow not possible
    largest_k = (n-y)/x * x + y // largest_k >= 0 and overflow not possible
    if (largest_k == 0) No_solution;
    

    x &lt; 0, 然后
    y &gt;= 0positive_int % x is never &lt; 0)
    y &lt; -xpositive_int % x is always &lt; -x)。*1
    (当涉及负值时,回想一下a%bnota mod b

    if (x < 0 && (y < 0 || y > -1 - x || y > n)) No_solution;
    

    其余分析遵循x &gt; 0案例,除了quotient &lt;= 0


    全部一起

    if (x == 0 || n < 1 || y < 0 || y > n) return No_solution;
    if (x > 0 && y >= x) return No_solution;
    if (x < 0 && y > -1 - x) return No_solution;
    
    int quotient = (n-y)/x;
    int largest_k = quotient * x + y;
    if (largest_k == 0) return No_solution;
    printf("Largest k: %d
    ", largest_k);
    

    *1y &lt; -x 可以重写为 y &lt;= -1 - x。此表单处理所有负 xincludingINT_MIN`。

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2019-09-21
      • 1970-01-01
      • 2019-02-23
      相关资源
      最近更新 更多