洛谷 P2399 non hates math

题目背景

non习惯将分数化成小数,但在数学中要以分数形式写,不能化成小数

因此non找到了会编程的你,帮助他将小数化回分数

题目描述

给出一个小数,将它化成假分数的形式

小数的类型有2种:(不考虑无限不循环小数)

普通小数

循环小数(会给出循环节)

(循环节用( )表示)

输入输出格式

输入格式:

 

一个小数n

 

输出格式:

 

输出这个小数n转化成最简分数的形式

 

输入输出样例

输入样例#1: 复制
1.32
输出样例#1: 复制
33/25
输入样例#2: 复制
1.(3)
输出样例#2: 复制
4/3
输入样例#3: 复制
1.0
输出样例#3: 复制
1/1

说明

输入小数的数据范围

0至1000

对于50%的数据保证没有循环节

对于20%的数据需要读入优化

思路:模拟即可。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[1001];
int l,r,num,num1,num2,num3;
int gcd(int x,int y){
    return x==0?y:gcd(y%x,x);
}
int pow(int a,int b){
    int s=1;
    for(int i=1;i<=b;i++)    s*=a;
    return s;
}
void work1(){
    int len=strlen(s),ans1,ans2;
    for(int i=len-1;i>=0;i--){
        if(s[i]>='0'&&s[i]<='9'&&(s[i+1]==')'||r)){
            num1+=pow(10,r)*(s[i]-'0');
            r++;
        }
        if(s[i]>='0'&&s[i]<='9'&&(s[i+1]=='('||l||s[i+1]=='.')){
            num2+=pow(10,l)*(s[i]-'0');
            l++;
        }
        if(s[i]=='.'){ ans1=l;ans2=r; }
    }
    l=num1-num2;r=pow(10,ans2)-pow(10,ans1);
    int GCD=gcd(l,r);
    printf("%d/%d",l/GCD,r/GCD);
    exit(0);
}
void work2(){
    int len=strlen(s);
    for(int i=len-1;i>=0;i--){
        if(s[i]>='0'&&s[i]<='9'){
            num3+=pow(10,num)*(s[i]-'0');
            num++;
        }
        if(s[i]=='.')    num1=num;
    }
    l=num3;r=pow(10,num1);
    int GCD=gcd(l,r);
    printf("%d/%d",l/GCD,r/GCD);
    exit(0);
}
int main(){
     cin>>s;
     int len=strlen(s);
     for(int i=0;i<len;i++)
         if(s[i]=='('){ work1();break; }
    work2();
}

 

posted @ 2018-03-11 14:52  一蓑烟雨任生平  阅读(183)  评论(0编辑  收藏  举报