1 题意。
2 分析。
①
参考的,a.它没有用递归,b.而且抽象出了Zero()函数,c.在细节上它让card[0]=0.0考虑到了小于0.5的情况(不用像自己写的还得特判)——【多想想某个递推的开始第一个值是不是需要为0】,是值得学习的。
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
const double delta=1e-8;
const int maxn=1010;
double card[maxn];
double CMP=5.20;
int Zero(double x){
if(x<-delta)//x<-delta,x is a negative real number
return -1;
else{ //return 0:x-delta<=0, because of"else", That is x==delta==0
return x>delta;//return 1:x-delta>0,x is a postive real number
}
}
int main()
{
//freopen("out.txt","w",stdout);
int star=0;
card[star++]=0.0;
for(int i=2;Zero(card[star-1]-CMP)<0;i++){
card[star]=1.0/(double)i+card[star-1];
star++;
}
double data;
scanf("%lf",&data);
while(Zero(data)){
int l=0;
int r=star;
while(l+1<r){
int mid=(l+r)>>1;
if(Zero(card[mid]-data)<0)
l=mid;//! l!=mid+1
else
r=mid;
}
printf("%d card(s)\n",r);
scanf("%lf",&data);
}
return 0;
}
②
自己写的,不是很标准,而且用了递归
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
const double delta=1e-8;
const int maxn=1010;
double card[maxn];
double CMP=5.20;
void Erfen(double t,int l,int r){
int mid=(l+r)>>1;
if(card[mid]<t&&card[mid+1]>t){
printf("%d card(s)\n",mid+1);
return ;
}
if(card[mid]<t){
Erfen(t,mid+1,r);
}
else if(card[mid]>t){
Erfen(t,l,mid);
}
return ;
}
int main()
{
//freopen("out.txt","w",stdout);
int star=1;
card[star++]=1.0/2.0;
for(int i=3;i<=1000;i++){
card[star]=(double)(1.0/(double)i)+card[star-1];
star++;
if(card[star-1]>CMP){
break;
}
}
card[star]=0;//boundary
double data;
while(~scanf("%lf",&data)){
if(fabs(data-0.0)<delta) break;
if(data<card[1]) printf("%d card(s)\n",1);
else if(data>card[star-1]) printf("%d card(s)\n",star-1);
else Erfen(data,1,star);
}
}