例题 2-2 3n+1问题
猜想:对于任意大于1的自然数n若n为奇数,则将n变为3n+1,否则变为n的一半。经过若干次的变换,一定会使n变为1。
例如3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 ->1。
输入n,输出变换的次数。n <= 10e9。
样例输入:
3
样例输出:
7
程序 2-4 3n + 1问题 (bug 乘法溢出)
#includeint main(){ int n; scanf("%d", &n); //定义一个计数器,变量count int count = 0; //n不为1进入循环 while (n != 1) { //n为奇数时 if (n % 2 == 1) n = 3 * n + 1; //否则为偶数 else n = n / 2; //执行一次循环体,计数器 +1 count++; } //输出计数器 printf("%d\n", count); return 0;}
当输入小的数字时,可以正常输出结果,而输入的是大数字如987654321,再执行 *3 操作,就会溢出。
因为int的范围是-231 ---232-解决办法是用C99引入的long long。只需将输入时的%d改为%lld。
程序 2-5 3n + 1问题
#includeint main(){ long long n; //将%d改为%lld scanf("%lld", &n); int count = 0; while (n != 1) { if (n % 2 == 1) n = 3 * n + 1; else n = n / 2; count++; } printf("%d\n", count); return 0;}
例题 2-3 近似计算
计算π/4 = 1 - 1/3 + 1/5 - 1/7 +……,直到最后一项小于10^-6。 程序 2-6 近似运算#include#include int main(){ double sum = 0; int i = 0; double term = 0; do { //注意1.0而非1 term = 1.0 / (2 * i + 1); if (i % 2 == 0) sum += term; else sum -= term; i++; }while(term > 1e-6); printf("%.6f\n", sum); return 0;}
虽然还是重复运算,但不同的是,只有算完一项之后才知道它是否小于10^-6。循环终止条件在计算之后,而非在计算之前。所以用do-while语句。