Sierpinski三角形的周长

时间:2015-07-13 15:09:04

标签: c++ c++11 math c++14

我正在为自己的练习做this problem。我设法通过所有的测试用例,所以我无法弄清楚什么是错的。我的代码是:

#include <iomanip>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
int main(){
   int num = 1;

   while(true){
    string line,stringRes;
    getline(cin,line);
    if(cin.eof()){break;}
    long double shrinks = atof(line.c_str());

    long double triangels = pow(3,shrinks);
    long double length = 3/pow(2,shrinks);
    long double res = floor(triangels* length * 3);
    int i = 0;
    while(res >= 10){
        i++;
        res =  res/10;
    };
    if(shrinks == 1){
        printf("Case %d: %d\n",num ,1);
    }else{
        printf("Case %d: %d\n",num ,i+1);
    }
    num++;
}
return 0;
}

例如,当我输入1000时,我得到178和10000,我得到1762。

输入样本

0
1
5
10
100

输出Samle

Case 1: 1
Case 2: 1
Case 3: 2
Case 4: 3
Case 5: 19

对于每种情况,显示案例编号,后跟表示给定迭代次数的圆周的整数部分所需的小数位数。遵循样本输出的格式。

2 个答案:

答案 0 :(得分:5)

你得到错误结果的原因是,如前所述:你通过使用pow获得溢出,但也因为你 - 你似乎已经意识到 - 使用3作为你的起始边长。

这是一个替代的,正确的解决方案,它有点短(没有溢出):

订单P(n)的Sierpinski三角形的周长(或周长)n >= 0可以显示为:

P(n) = 3^(n + 1) / 2^n

我没有提供证明,因为没有必要解决问题。但是,很容易理解必须如此。一种方法是计算Sierpinski三角形的前几个阶的周长:39/227/481/8,...,另一种方法是考虑当你(1)将形状“缩小”1/2并且(2)将三角形“延伸”3倍时,周长如何变化。

任何自然数(基数为10)D(x)中的位数x为:

D(x) = 1 + floor(log10(x))

因此,为了计算订单n的Sierpinski周长中的小数位数,我们计算P(n) = 3^(n + 1) / 2^n的整数部分中的位数,即D(floor(P(n))),这也是解决问题的方法:

D(floor(P(n))) = 1 + floor(log10(3^(n + 1) / 2^n)) = /log(a/b) = log(a) - log(b)/ =
= 1 + floor(log10(3^(n + 1)) - log10(2^n)) = /log10(a^b) = b * log10(a)/ =
= 1 + floor((n + 1) * log10(3) - n * log10(2))

解决问题的C ++实现:

/** Calculates the number of digits in the integer part of the perimeter of the Sierpinski triangle of order n */
/** Author: Fredrik Präntare, Date: 19/3/2016 */
#include <iostream>
#include <algorithm> // log10, floor
using namespace std;

int main(){
    int c = 1, n;
    while(scanf("%d", &n) != EOF){
        int D_p = 1 + floor((n + 1) * log10(3) - n * log10(2));
        printf("Case %d: %d\n", c, D_p);
        c++;
    }
}

答案 1 :(得分:2)

你溢出了triangels的价值。当你有

long double triangels = pow(3,shrinks);

shrinks = 10000给出的地方:1.6313501853426258743032567291812e + 4771。

sizeof(long double) == 8为1.7E +/- 308的长双倍范围。

您很可能需要使用modular exponentiation来解决此问题。