更多JAVA版答案移步我的博客:蓝桥杯JAVA版答案汇总
本题考查
- 前置知识1:定理:一个分母为N的循环小数的循环节位数最多不超过N-1位
- 前置知识2:数A小于数B。若A/B为无限循环小数的话,则在出现循环节之前,每次长除法的余数都不相同,如下图所示,红框中的数字即使每次长除法的余数。当出现相同余数时(假设本次计算出的余数
y
与前面的某个余数相同)即说明前面计算余数为y的后一位到该位之间(包括该位)所有小数组成了循环节。也就是下图中的076923,第二个零是计算余数为1的数位的后一位,而最后的3是计算余数为3的数位。
思路
- 为保证a小于b,首先计算a%b并将至赋给a
- 模拟长除法,并将每次计算余数加入链表中,当链表中出现重复元素,即长除法出现相同余数时,说明出现循环节。记录循环节第一个元素索引
start
,最后一个元素索引end
,若两数相除不是无限循环小数,则置start
为-1 - 输出时进行判断,若结果是无限循环小数则步骤4;否则步骤5
- 对于无限循环小数输出时,需要注意当前输出索引是否在循环节内,因为一定所有的无限循环小数循环节都是从小数点后第一位开始的
- 需要判断索引是否超出数组界限,超出的话输出0
AC代码
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
LinkedList<Integer> list = new LinkedList<Integer>();
int a = scaner.nextInt();
int b = scaner.nextInt();
int n = scaner.nextInt();
scaner.close();
a=a%b;
int[] num = new int[b];
int start = 0; int end = 0;
loop:
while(a!=0&&end<b) {
if(!list.contains(a)) {
list.add(a);
num[end++]=(int)(a*10)/b;
a=(a*10)%b;
}
else {
for(int i=0; i<list.size(); i++)
if(list.get(i)==a) {
start = i;
end--;
break loop;
}
}
if(a==0) start=-1;
}
if(start==-1)
for(int i=n-1; i<n+2; i++)
if(i<b-1) System.out.print(num[i]);
else System.out.print(0);
else
for(int i=n-1; i<n+2; i++)
if(i<start) System.out.print(num[i]);
else System.out.print(num[(i-start)%(end-start+1)+start]);
}
}