有人可以向我解释这个CodeForces 919B / Perfect Number解决方案吗?

时间:2018-02-01 18:56:41

标签: c++

这是我发现CodeForces问题919B - Perfect Number的解决方案。 我在技术上理解它在做什么,但我想理解它背后的“直觉”或想法/方法。

int main(){
    int k=0, m=19, c=0, sum=0;
    scanf("%d", &k);
    while(true){
        int n = m;
        sum = 0;
        while(n){
            sum+=n%10;
            n=n/10;
        }
        printf("%d %d %d\n", n, sum, c);
        if(sum == 10) c++;
        if(c == k) break;
        m++;
    }
    printf("%d", m);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

用户0x499602D2已经给出了非常简洁的答案,但让我详细说明一下。超高级伪代码看起来像这样:

loop over natural numbers and check if they are perfect:
  if found k such numbers: 
    stop and output the last perfect number

这是一个更详细的伪代码,与您的c ++代码相匹配:

m   = 19 # first perfect number (1+9=10) - a good starting point
c   = 0  # total number of perfect numbers found so far
sum = 0  # temporary variable that will hold the sum of digits

read k from stdin # we're going to look for the k-th perfect number 

# we start an open-ended search but we know that we will find k-th number and stop
for m = 19 ... infinity:
  if m is perfect:
    increment c by one        # found c perfect numbers so far

  if c == k:           
    exit loop and return m    # m is the k-th perfect number! we're done!

了解c如何与我们找到的“完美数字”的数量相对应?一旦c点击k,我们的循环就会停止。

还有一个技术问题:我们如何检查1945号码是否完美?我们需要将数字相加:1 + 9 + 4 + 5。从数字n获取最低有效数字的简单方法是将除法的余数除以10(即n modulo 10):

1945 % 10 = 5
194  % 10 = 4
19   % 10 = 9
1    % 10 = 1

如何从1945到194到19到1?只需按10进行整数除法:

1945/10 = 194
 194/10 = 19
  19/10 = 1
   1/10 = 0 -> stop the loop, since while(0) is the same as while(false)

这就是printf之前发生的事情。