0
点赞
收藏
分享

微信扫一扫

2972. 分数的精确值

爱写作的小土豆 2022-04-14 阅读 26
c++

题目描述:

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;
			}
		}
	}
} 
举报

相关推荐

0 条评论