分数转小数

​ 参加了学校的程设比赛,虽然脑子没有全程闲着但是输出为零这个真不假,全靠队友带。但这个数学题是@qrzbing给了我思路然后我去写,结果,写挂了。。。思路是没错的,然而我对细节的处理不够到位,导致这个题到最后都没能调出来,真的可惜。比赛完后去搜索了一下别人的解法,比对并记录一下。

​ 题目就不贴了,懒得拍照上传(不仅是英文的,还一堆废话),大概要求输入是一个整数T,代表数据组数,后面的T行每行一个整数n和m,表示n除以m,输出为小数,比如这样:

输入:4 2 3 1 2 22 7 7 12

输出:0.(6) 0.5 3.(142857) 0.58(3)

​ 队友给了我思路,小数部分的求法其实就是余数乘以10再不断除以m得到商以及下一个余数,如果余数开始相等,说明再一次进入了循环,所以全程都不需要用浮点数的。我的想法很简单直接,就是用两个数组分别去保存商和余数,通过判断余数是否有和前面的余数相同来判断是否进入了循环结构,然后打印商的那个数组就好了,理论上可行,但是在判断开始循环的位置时出现了问题,怎么打印都不对,具体错在哪也不是很清楚了,因为被队友魔改了一波,细节处理那段代码以及可以说不是我写的代码了。

​ 看了github上的某段代码后,感觉自己对数据的处理能力真的好差啊啊啊啊啊啊啊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
using namespace std;
int main() {
int t;//组数
cin >> t;
while ( t-- ) {
int n, m;//n是被除数,m是除数
cin >> n >> m;
int k, j, i = 1, flag = 0, l = 0, a[1001] = {n}, lab = 0, b[1001];
if ( n > m ) {
cout << a[0] / m;//大于1先输出整数部分
a[0] %= m;//a[0]换成模
}
else {
cout << 0;
}
cout << ".";
while ( 1 ) {
k = a[i-1] * 10 / m;//k就是商,也就是小数位,最后要输出的东西
a[i] = a[i-1] * 10 % m;//更新模
b[l++] = k;//记录小数位
if ( a[i] == 0 ) {//表示可以除尽的情况,比如1/2
lab = 2;//对这种情况标记
break;
}
for ( j = 0; j < i; j++ ) {
if ( a[j] == a[i] ) {//这里是去找余数相同的位置了,也就是循环开始的地方
lab = 1;
flag = j;//用flag标记这个下标
break;
}
}
if ( lab == 1 || lab == 2 ) {
break;
}
i++;
}
for ( i = 0; i < l; i++ ) {
if ( flag == i && lab == 1 ) {//到了循环标记位加括号
cout << "(";
}
cout << b[i];
}
if ( lab == 1 ) {
cout << ")\n";
}
else {
cout << "\n";
}
}
return 0;
}

​ 仔细研究了这段代码后发现,我就是错在开始循环的时候忘记去判断了!!!我TM!!!

好吧我还是太菜了,打扰了。看来程设比赛的基本套路也是需要练的,顺便还想吐槽的就是为什么一个队只给一台电脑啊。。。再顺便吐槽一下校赛的运维,恶恶魔魔麻麻秘密摸咪咪

!!!我后期一定好好学一下数论,至少得会基本的东西。