poj3358 Period of an Infinite Binary Expansion

WA的代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
#define LL long long
#define maxn 1000+5//最多的小数位数
using namespace std;
double a[maxn];
const double eps=1e-10;
double abs(double n)
{
    return n>0 ? n:-n;
}
int find(int cnt)//关键
{//判断第cnt个数是否在前面出现过
    for (int i=1;i<cnt;i++)
    {
        if (abs(a[i]-a[cnt])<eps) return i;
    }
    return 0;
}
int main()
{
    LL n,m;
    int cas=0;
    while(~scanf("%I64d/%I64d",&n,&m))
    {
        cas++;
        double ans=(n+0.0)/(m+0.0);
        ans=ans-(int)ans;
        int cnt=1;a[1]=ans;
        int ch;
        while ( (ch=find(cnt))==0 )
        {
            ans=ans*2;
            ans=ans-(int)ans;//应该判余数
            cnt++;
            a[cnt]=ans;
        }
        printf("Case #%d: %d,%d
",cas,ch,cnt-ch);

    }
    return 0;
}

我们主要来说说是怎么WA的

一句话总结,正确的算法,有限的存储精度。

思路描述:

1、原理:重复乘2,取首位。

然后我就就想简化判断,只要出现重复的小数部分,那一定是又开始了一个新的循环。

2、结果悲剧了,错误有二:

i.  double型的好像不能直接判断a==b,会有判断误差,反正像是0.2==0.2这样的都判断不出

ii.  后来我就想通过eps约束,(abs(a-b)< eps ), 一直W,后来才想到,比如1/199213,这样的数据,它本身的小数部分就有10^6位,计算机是不可能存储下来的,double本来就是模糊存储。  再者,eps不可能兼顾所有的数据  (以后少用)。

下面是AC的代码

原文地址:https://www.cnblogs.com/little-w/p/3294276.html