习题2-4 子序列的和(subsequence)
输入两个正整数n<m<106,输出 ,保留5位小数。输入包含多组数据, 结束标记为n=m=0。提示:本题有陷阱。
样例输入:
2 4
65536 655360
0 0
样例输出:
Case 1: 0.42361
Case 2: 0.00001
收获
这题看起来简单,但是敲完,然后书本给的测试数据都过不了。
输出:
2 4
Case 1: 0.42361
65536 655360
Case 2: inf
自己先认真思考,嗯真的挺认真的,想不出来,然后查阅了资料,看了前辈的各种见解。发现就是前几天刷OJ的一个问题,先乘后除然后数据溢出了。inf表示infinite(无穷大),超过浮点数的表示范围,就是阶码部分溢出了。(我心里想着这不是没溢出,数不会很大来着,既然它解释说阶码部分溢出,那还能理解一点点)。解决方法就是:
//sum += (1.0) / (i * i); 会溢出
//改成先除法即可
sum += (1.0) / (i*1.0) / (i*1.0);
习题2-5 分数化小数(decimal)
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<=100。输入包含多组数据,结束标记为a=b=c=0。
样例输入:
1 6 4
0 0 0
样例输出:
Case 1: 0.1667
哔哔赖赖
我本以为用c++的保留小数点后的位数setprecision()函数即可,然后看了一些博客,说double最多精确到小数点后16位,再多没有了!
自己试了一下,输出三分之一,是这样!然后学到了,可以采用自己模拟除法的方法,就可以解决这个问题,这样想输出小数后10000位都不是问题。
乘10取余法——这个方法就是先算整数部分,剩下的小数部分不断乘10取余即可。这里放个例子,会更容易理解:1.0 / 8.0, 整数部分为0,小数部分计算:1乘10 再除以8,整除得1,取余得余数2。1就是第一位小数了,剩下继续 2乘10再除以8,整除得2,取余得余数4。继续,4乘10 再除以8,整除得5,取余得0,计算结束,得值0.125。
代码实现
#include <iostream>
//#include <iomanip> //cout输出小数后的位数 ,这是改动前的代码
using namespace std;
int main() {
int a,b,c;
while (scanf("%d%d%d", &a, &b ,&c) != EOF) {
if(a==0 && b==0 && c==0) break;
// double res = (a*1.0) / b;
// cout.setf(ios::fixed); //自动补尾数的0
// cout << fixed << setprecision(c) << res << endl;
int z = a / b; //整数部分
a = a - z * b; //去掉能整除部分后的a的值
cout << z << "."; //输出整数和小数点
//由于最后一位小数要四舍五入,所以我们先输出到第(c-1)位
for (int i = 0; i < c-1; i++) {
cout << a * 10 / b;
a %= b;
}
//处理最后一位小数,四舍五入
int last , judge;
last = a * 10 / b;
a %= b;
judge = a * 10 / b;
if (judge >= 5) last++;
cout << last << endl;
}
return 0;
}
输出
PS:突然在想,我写博客的初衷是什么呢?
嗯,是想记录自己的成长过程、收获的点点滴滴,并且想着能把思路写出来,可以加深自己的理解。加油鸭!!!:)
习题2-6 排列(permutation)
用1,2,3,…,9组成3个三位数abc、def、ghi,每个数字恰好使用一次,要求abc:def:ghi = 1:2:3。提示:不必太动脑筋。
嗯,没错!它说不要太动脑筋,我差点就想直接全部把三位数用三个循环遍历一遍了,总共有900900900种情况。。。
但是这代码写得傻就算了,还麻烦,真的是又臭又长,我最终放弃了这个想法,战略性跳过,然后放下书,打游戏去了。
今天搜C++的STL的简介的时候,看到了permutation这个函数,可以输出数组中数的全部排列!!!我去,那我不是直接用!!!用“轮子”真的是美滋滋,下面是代码
代码实现
#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(void){
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
//使用C++中的net_permutation函数生成数组的全排列
do{
int a = arr[0]*100 + arr[1]*10 + arr[2];
int b = arr[3]*100 + arr[4]*10 + arr[5];
int c = arr[6]*100 + arr[7]*10 + arr[8];
if (a == (b*1.0)/2 && a == (c*1.0)/3) {
printf("%d%d%d %d%d%d %d%d%d\n", arr[0],arr[1],arr[2],arr[3],arr[4],arr[5],arr[6],arr[7],arr[8]);
}
}while(next_permutation(arr, arr + 9));
return 0;
}