【问题标题】:Finding partial sum without using loops不使用循环查找部分总和
【发布时间】:2021-02-20 19:21:33
【问题描述】:

问题如下:

编写一个程序,提示用户输入一个正整数 m,它表示一本书中所有页码的总和。该程序打印该数字是否为有效总和。例如,整数 21 是页码的有效总和,因为 1 + 2 + 3 + 4 + 5 + 6 = 21。整数 25 不是有效总和,因为前 6 个页码的总和是 21,下一个页码为 7,因此前 7 个页码的总和应为 28。如果 m 是所有页码的有效总和,则必须有一个整数 n,使得 1+2+3+ ... + n = n( n+1)/2 = m

这是我的代码:

#include <iostream>
using namespace std;
int main() {
    int num,n=0,sum=0;
    cout<<"Enter a positive integer"<<endl;
    cin>>num;

    for (int i=1;i<num;i++){
        sum+=i;
        n++;
        if (sum==num)
            break;
 }
        if (((n*(n+1))/2)==num){
            cout<<"This number is valid";

        }
        else{
            cout<<"This number is invalid";

        }


}

代码正在运行,但我需要另一种方法来实现这个程序,而不使用循环,而只使用选择语句。可以这样做吗??

【问题讨论】:

标签: c++ loops for-loop nested


【解决方案1】:

稍微重新排列方程:

n(n+1)/2 = m
n(n+1) = 2m

现在,要使这个等式成立,sqrt(2m) 必须介于nn+1 之间,即n = floor(sqrt(2m))n+1 = ceil(sqrt(2m))。然后您可以检查nn+1 的计算值是否与2m 相乘。使用代码检查很简单:

#include <iostream>
#include <cmath>

int main(){
    int num;
    std::cout << "Enter a positive integer\n";
    std::cin >> num;
    float a = std::sqrt(2 * num);
    if(std::floor(a) * std::ceil(a) == 2 * num){
        std::cout << "This number is valid\n";
    } else{
        std::cout << "This number is invalid\n";
    }
}

请注意,我稍微清理了您的代码。欲了解更多信息,请查看Why is "using namespace std;" considered bad practice?"std::endl" vs "\n"

【讨论】:

  • 我不明白你为什么使用 std::floor 和 std::ceil 你能解释一下吗
  • sqrt(2m) 介于 n 和 n+1 之间,但 n 和 n+1 之间的差距是 1,这意味着 sqrt(2m) 是这两个整数之间的分数。
  • 例如,对于 m=21,sqrt(2m) = 6.48074069840786,表示 n 为 6,n+1 为 7,符合方程。
  • int a = std::sqrt(2 * num); if(a * (a+1) == 2 * num) 不会更简单吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多