【2014广州市选day1】倒数运算
Description
倒数,顾名思义就是用1除以被倒数得出的结果,例如2的倒数是0.5,0.5的倒数是2。现在我们需要获得正有理数的倒数。
正有理数的表示格式:
<整数部分> + [小数点]+ [小数非循环部分] [(循环部分)]
其中 <> 为必填部分, []为可选部分, 如果选了小数点,则后面肯定有小数部分
正有理数的表示要求:
整数部分十位数字以后不能有多余的0,如 00123 是非法的有理数
小数后面不能有多余的0,如 0.123000 , 0.12(0) 是非法的有理数
可以放进循环部分的小数一定要放进循环部分,不能留在非循环部分,如 0.123(3) ,12.123234(234) 是非法的
小数循环部分不能是 (9),如果是(9)则需要进一处理,如 0.(9)=1 , 0.2(9)=0.3
Input
输入只有一行,代表一个正有理数,符合上述的有理数表示要求,每一行最多100个字符。
Output
输出一行,代表输入的正有理数的倒数,要求符合上述有理数的表示要求。
输入数据保证输出的正确答案不超过100个字符。
Sample Input
Sample Input1
3
Sample Input2
0.(3)
Sample Output
Sample Output1
0.(3)
Sample Output2
3
题解
就是将有理数转分数,取倒数就分母分子换一下,不过要打高精度,细节很多,考试时没打。
先考虑小数,假设有一个数
转成分数后是这样的
再打个高精度除法
证明
设x=0.(9) ①
10x=9.(9) ②
①-②得 9x=9
∴x=1
其它证明类似
code
代码有点丑
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define R register
#define ll long long
using namespace std;
struct node{
int s[5000],len;
}s1,s2,s3,m,n,k,a1,a[100];
int ans[200],cnt,bj=0,s,t;
inline void update(node &a){while(!a.s[a.len]&&a.len)--a.len;}
inline void read(node &x){
if(bj)return;
x.len=0;
int k;
for(char ch=getchar();isdigit(ch);ch=getchar(),bj=ch=='\n')
x.s[++x.len]=ch^48;
for(R int i=1;i<=x.len/2;++i)k=x.s[i],x.s[i]=x.s[x.len-i+1],x.s[x.len-i+1]=k;
}
inline node power(int x){
node re;
re.len=max(0,x)+1;
for(R int i=1;i<re.len;++i)re.s[i]=0;
re.s[re.len]=1;
return re;
}
inline node add(node a,node b){
node re;
re.len=max(a.len,b.len),re.s[1]=0;
for(R int i=1;i<=re.len;++i){
re.s[i]+=a.s[i]+b.s[i];
re.s[i+1]=re.s[i]/10;
re.s[i]%=10;
}
if(re.s[re.len+1])++re.len;
update(re);
return re;
}
inline node mul(node a,node b){
node re;
int k;
re.len=a.len+b.len-1;
for(R int i=1;i<=re.len+1;++i)re.s[i]=0;
if(!a.len||!b.len){re.len=0;return re;}
for(R int i=1;i<=a.len;++i){
for(R int j=1;j<=b.len;++j){
re.s[i+j-1]+=a.s[i]*b.s[j];
re.s[i+j]+=re.s[i+j-1]/10;
re.s[i+j-1]%=10;
}
}
if(re.s[re.len+1])++re.len;
return re;
}
inline int judge(node a,node b){
if(a.len>b.len)return 1;
if(a.len<b.len)return 0;
for(R int i=a.len;i;--i){
if(a.s[i]>b.s[i])return 1;
if(a.s[i]<b.s[i])return 0;
}
return 2;
}
inline node minus(node a,node b){
node re=a;
for(R int i=a.len;i;--i){
re.s[i]-=b.s[i];
if(re.s[i]<0)re.s[i]+=10,--re.s[i+1];
}
update(re);
return re;
}
inline node div(node &a,node b){
node re,c;
re.len=0,re.s[1]=0;
for(R int i=a.len-b.len,v=0;i>=0;--i)
if(judge(a,(c=mul(b,power(i))))||v){
re.s[++re.len]=0,v=1;
while(judge(a,c))
a=minus(a,c),++re.s[re.len];
}
int k;
for(R int i=1;i<=re.len/2;++i)k=re.s[i],re.s[i]=re.s[re.len-i+1],re.s[re.len-i+1]=k;
return re;
}
inline void put(node x){
if(!x.len)printf("0");
for(R int i=x.len;i;--i)printf("%d",x.s[i]);
}
int main(){
read(s1),read(s2),read(s3);
m.len=n.len=0,a1.s[a1.len=1]=1;
for(R int i=1;i<=s2.len;++i)m.s[++m.len]=0;
for(R int i=1;i<=s3.len;++i)m.s[++m.len]=9;
if(!s3.len)m.s[++m.len]=1;
update(s2);
if(!m.len)m.s[1]=m.len=1;
n=add(mul(s1,m),add(mul((s3.len==0?a1:minus(power(s3.len),a1)),s2),s3));
update(n),put(div(m,n)),bj=1;
while(m.len){
m=mul(m,power(1)),ans[++cnt]=div(m,n).s[1],a[cnt]=m;
for(R int i=1;i<cnt;++i)
if(ans[i]==ans[cnt]&&judge(a[cnt],a[i])==2)
s=i,t=--cnt,bj=0;
if(!bj)break;
}
if(cnt){
printf(".");
for(R int i=1;i<=cnt;++i){
if(i==s)printf("(");
printf("%d",ans[i]);
if(i==t)printf(")");
}
}
}