题目描述:
Problem #2972 - ECNU Online Judgehttps://acm.ecnu.edu.cn/problem/2972/
分析思路:
example:
4/7的计算过程:
4/7=0余4,即结果为0余数为4;
4*10=40、40/7=5余5,即结果为0.5余数为5;
5*10=50、50/7=7余1,即结果为0.57余数为1;
1*10=10、10/7=1余3,即结果为0.571余数为3;
3*10=30、30/7=4余2,即结果为0.5714余数为2;
2*10=20、20/7=2余6,即结果为0.57142余数为6;
6*10=60、60/7=8余4,即结果为0.571428余数为4;
由于在计算过程中余数4出现过,后面的计算过程即将重复
由此可见,我们需要两个数组,一个用来记录商(即quotient),另一个用来记录余数(即remainder)
用来记录商的数组是用来输出答案的,即example中的0571432(输出时要写成0.571432)。
用来记录余数的数组是用来判断是否有循环节的。
我们知道,如果本次除法的余数m在之前也作为余数出现过,接下来的计算过程就会完全重复。
因此设置数组quotient,quotieme[m] = i 表示的是余数m在第i个位置上出现过(因此在开始算之前,要全部初始化成无效位置-1)。
比如在example里,第一次会记quotient[4]=0, 第二次会记quetient[5]=1 ....直到发现,quotient[4]里已经有一个有效值0(而不是-1)了,则表明4这个余数出现过,就可以输出 quotient[4]-现在的位置 表示是一个循环节。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAXN 110
using namespace std;
void initialize(int *a,int *b){
for(int i=0;i<MAXN;i++){
a[i]=-1;
b[i]=0;
}
}
int main(){
int T;
int remainder[MAXN];
int quotient[MAXN];
int m,n;
cin>>T;
for(int t=0;t<T;t++){
scanf("%d %d",&m,&n);
initialize(remainder,quotient);
for(int i=0;;i++){
remainder[m]=i;
m*=10;
quotient[i]=m/n;
m=m%n;
if(m==0){
cout<<"case #"<<t<<":"<<endl;
cout<<"0.";
for(int k=0;k<=i;k++){
cout<<quotient[k];
}
cout<<endl;
break;
}
if(remainder[m]!=-1){
cout<<"case #"<<t<<":"<<endl;
cout<<"0.";
for(int k=0;k<=i;k++){
cout<<quotient[k];
}
cout<<endl;
cout<<remainder[m]+1<<"-"<<i+1;
cout<<endl;
break;
}
}
}
}