USACO 2.4.5 分数化小数 Fractions to Decimals

题解

想出来的解法比较暴力。
前提知识:能够用整数表示出的小数都是有理数,所以不会存在无限不循环小数(无理数)。
判断是否无限循环,遍历小数点后100-200位若全是0那肯定不是无限小数 ( 确实存在后面这么多0的无限小数,但不在题目数据范围内 ),否则肯定无限。
若无限循环就要找环,环长怎么样?从头到尾数相同,暴力遍历即可。
最后注意 N 要开大点。


Code

// head files excluded
using namespace std;
const int N = 60000;
int n,m,k;

int cot[N];
int p[2];
void dvd(int a,int b){ // division a/b -> cot[]
    k=0;
    int s = a/b;
    int y = a%b;
    cot[k++]=s;

    while(y!=0){
        y*=10;
        s = y/b;
        cot[k++] = s;
        y = y%b;

        if(k>N-1)break;
    }
}

bool isll(){ // is limitless cycle ?
    int sum=0;
    for(int i=100;i<200;i++){
        sum+=cot[i];
    }
    if(sum == 0) return false;
    return true;
}
void cycler(){// calc for the start & end of the cycle -> p[]
    int s,e;
    bool fd=false;
    for(int i=1;i<200;i++){
        for(int j=i+1;j<N;j++){
            if(cot[i]==cot[j]){
                s=i;
                e=j;
                while(cot[s]==cot[e]){
                    s++;
                    e++;
                    if( s-i>200) {
                        fd=true;
                        break;
                    }
                }
                if(fd){ 
                    p[0]=i;
                    p[1]=j;
                    return;
                }
            }
        }
    }
    return ;
}
int main(void){

    cin>>n>>m;
    dvd(n,m);
    int ct=0;
    cout<<cot[0]<<".";

    if(cot[0]==0) ct++;
    while(cot[0]!=0){
        cot[0]/=10;
        ct++;
    }
    ct++;

    if(!isll()){
        if(k>1) k--;
        for(int i=1;i<=k;i++){
            cout<<cot[i];
            ct++;
            if(ct >= 76){
                ct=0;
                cout<<endl;
            }
        }
    }else{
         cycler();
        for(int i=1;i<p[0];i++) {cout<<cot[i];
            ct++;
            if(ct >= 76){
                ct=0;
                cout<<endl;
            }
        }
        cout<<"(";
        ct++;
        for(int i=p[0];i<p[1];i++) {
            cout<<cot[i];
            ct++;
            if(ct >= 76){
                ct=0;
                cout<<endl;
            }
        }
        cout<<")";
    }
    cout<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值