算法竞赛入门经典第二版 第二章习题及思考题
Posted 163467wyj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法竞赛入门经典第二版 第二章习题及思考题相关的知识,希望对你有一定的参考价值。
enmmmmmm】 大部分好像除了最后一个思考题都很简单
代码如下
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> int main(){ /* for(int i =100 ; i <= 999 ; i++) { int a = i/100;int c = i%10;int b = (i-a*100)/10;//水仙花数 if( i == pow(a,3)+pow(b,3)+pow(c,3)) WA //if( i == a*a*a+b*b*b+c*c*c) //AC printf("%d= %d^3 + %d^3 + %d^3 ",i,a,b,c); }*/ /*int a,b,c,kase=1;//2-2hanxin韩信 while(scanf("%d%d%d",&a,&b,&c) == 3 )//3 5 7 { int flag =0; printf("Case %d: ",kase++); a = a*70+b*21+c*15; while(a >= 105){ a -= 105; } if(a <=10 || a>=100 )printf("No answer "); else printf("%d ",a ); //for(int i = 10;i <= 100 ; i++) // if(i%3==a && i%5==b && i%7==c) // {printf("%d ",i);flag=1;} //if(!flag) printf("No answer " ); }*/ /* int n;scanf("%d",&n);//2-3triangle倒三角形 for(int i = n;i >= 1 ;i--) { for(int j = n-i ;j > 0;j--)printf(" "); for(int j = i*2-1;j > 0;j--)printf("#"); for(int j = n-i ;j > 0;j--)printf(" "); printf(" "); }*/ /*int n,m;while( scanf("%d%d",&n,&m)==2 ) {//2-4子序列的和 subsequence if(n == 0 && n == m)break; double ans = 0.0; for( int i = n ; i <= m;i++) { ans += (1.0/i)*(1.0/i); //直接1.0/(i*i)就炸 //sum += 1 / (((double)n + i) * ((double)n + i)); //在n较大时,((double)n + i) * ((double)n + i)会溢出, //所以应该改成 1 / ((double)n + i) / ((double)n + i) //printf("i=%d ans=%.5lf ", i,ans); }printf("%.5lf ", ans);//printf("%u %u ", -1,-2); }*/ /* int a,b,c,n,n1; while(scanf("%d%d%d",&a,&b,&c)==3 && (a||b||c)) { for(int count=0; ;count++) { if(count) { if(count<=c) printf("%d",n); else { if(n1=a/b >= 5) n++; printf("%d",n); break; } n=a/b; a=(a-n*b)*10; if(count == 1) std::cout<<"."; } } } int a,b,c,kase=0,i; while(scanf("%d%d%d",&a,&b,&c)&&a&&b&&c){ printf("Case %d: %d.",++kase,a/b); a%=b; for( i = 1; i < c; i++){ printf("%d",a*10/b); a=a*10%b; } if( a*10%b*10/b >= 5) a*10/b++; printf("%d ",a*10/b); }*/ /* int a,b,c;//2-5分数化小数 decimal while(scanf("%d%d%d",&a,&b,&c)==3 ){ if( a== b && b==c && a==0)break; int aa[505],bb[505]; aa[0] = a/b; aa[1] = a*10/b; for(int i=2; i <= c+1;i++) { bb[i] = a*10%b; aa[i] = bb[i]*10/b; }//printf("%d.",aa[0]); if(aa[c+1] >= 5 )aa[c] += 1; for(int i=c; i >= 1 ;i--) if(aa[i] == 10) aa[i]-=10,aa[i-1]+1; printf("%d.",aa[0] ); for(int i=1; i < c; i++) printf("%d",aa[i] ); printf("%d ",aa[c]); } int a,b,c;while(scanf("%d%d%d",&a,&b,&c) == 3 && a){ //if(a <= 1e+6 && b <= 1e+6 && c <= 200 && a != 0 && b != 0 && c != 0){ printf("%.*lf ",c,(double)a / (double)b); //} }*/ /*for(int i=123; i <= 333; i++) {//排列 bool aa[10]={false}; int flag =0 ; aa[i/100] = aa[i/10%10] = aa[i%10]=true; int j = i*2; int k = i*3; aa[j/100] = aa[j/10%10] = aa[j%10]=true; aa[k/100] = aa[k/10%10] = aa[k%10]=true; for(int d= 1; d <= 9; d++) { if( aa[d] == false ) {flag=1;break;} } if( !flag ) printf("%d:%d:%d ", i,j,k); } int n;scanf("%d",&n); for(int i = 1; i <= n; i++)//for(int i = 2; i <= n; i+=2) printf("%d ", 2*i);*/ double i = 0; for( i = 0; i != 10; i += 0.1) printf("%f", i); return 0; }
至于最后一个思考题 浮点数陷阱
把 10 改成10.0 10.000000 啥的都没用 脑阔疼 搜了下发现了这个博客 http://blog.sina.com.cn/s/blog_6da76f9b0100yr8d.html
浮点数陷阱:
之所以无限循环,那么就可以推断是for循环的条件始终成立,即 i 始终不等于10.
是因为浮点数的原因. 我们把10改成10.0,结果仍然是无限循环.
是浮点数的加法运算引起的.
调用gdb输出中间结果来观察,发现 i 自加0.1后,并不是我们预想的等于0.1
而是等于 0.10000000000000001.
再往下执行几次,i 的值分别是0.20000000000000001.
0.30000000000000004.
0.40000000000000002.
所以程序不会终止 因为浮点数在进行小数运算的时候由于
精度问题,会有很小的误差,然而用 = 或者 != 这样的运算符来比较,是会检测出这种
误差的.所以导致结果的不正确.
将循环条件改为 i != 0.1 或者 i != 0.2时,程序能够正常运行,得到正常结果.但是当i != 0.3时,就是无限循环.显然,在我们的程序中,这种
不确定的错误是不应该存在的.
因此,在定义循环变量时,尽量采用int型及整数的加减.因为循环的本质意义就是 通过各种条件来控制语句重复运行次数.而这个次数本身就是整数.要实现小数的功能 尽量通过循环中的语句来实现.
以上是关于算法竞赛入门经典第二版 第二章习题及思考题的主要内容,如果未能解决你的问题,请参考以下文章