此题巨坑!
题目链接:ZOJ1210-Reciprocals
在此转到关于本书博客ACM大学生程序设计竞赛在线题库最新精选题解(赵端阳)部分解析
话说本书这个代码真的能过样例吗?tmd样例都过不了还好意思发代码??
先放一张我的ac:
简单说下本题思路,书上算法分析没问题,就是实现很迷:
本题输入总可以写成2x ∗ * ∗ 10y或者5x ∗ * ∗ 10y;所以首先去掉这个数的后缀零,然后输出时补上y-1个零即可。
其次判断前面数究竟是2或者5的多少次方。众所周知,5的n次方末尾永远是5,所以去掉零后判断末尾是不是5(如果末尾是1的话不用我说了吧),如果是5那基数就是5,否则就是2,可以封装一个函数判断减去末尾零后的数是几次方,其实有个简单方法就是当不断乘5或2(基数)的数和原数一样长的时候,判断首位是不是一样就行了。这样的话只需要知道基数和原数长度即可,函数如下:
int pw(int bas, int l) {
//基数bas和原数长度l
int inum[100] = {
0 };
inum[1] = 1;//2或5的0次方就是1啦
int pw = 0;//需要求的次方数
int len = 1;
int c;
while (inum[l] != (s[0]-'0')) {
判断相同长度时首位是不是一样
len++;
pw++;
c = 0;
for (int i = 1; i <= len; i++) {
c += inum[i] * bas;
inum[i] = c % 10;
c = c / 10;
}
if (inum[len] == 0)len--;
}
return pw;
}
注意书上判断直接用了double e来存数这是连样例都过不了的!早已经超过long long精度了。
最后补上0即可,补零就是补乘方后的数位数减1即可(可以自己推下):
zero = len - 1;
本题出的也非常坑。提交格式还wa了一发,格式虽然题目说清了但是也太复杂了吧呜呜呜~,格式第一行注意得这么输出:分号两边有空格,等号右边是没有空格的。
printf("\n1 / %s =\n", s);
zoj对scanf读入字符永远有偏见似得,无论怎么改scanf输入总是TLE。所以只能用gcc 6.4.0编译使用gets()函数读入。
AC代码:
#include<math.h>
#include<stdio.h>
#include<string.h>
char s[100];
int pw(int bas, int l) {
int inum[100] = {
0 };
inum[1] = 1;
int pw = 0;
int len = 1;
int c;
while (inum[l] != (s[0]-'0')) {
len++;
pw++;
c = 0;
for (int i = 1; i <= len; i++) {
c += inum[i] * bas;
inum[i] = c % 10;
c = c / 10;
}
if (inum[len] == 0)len--;
}
return pw;
}
int main() {
int t[100];
printf("Problem 4 by team x\n");
while (gets(s)){
printf("\n1 / %s =\n", s);
int len = strlen(s);
int zero = 0;
for (int i = len - 1; i >= 0; i--)
if (s[i] == '0')zero++, len--;
else break;
if (s[len - 1] == '1') {
printf("0.");
for (int i = 0; i < zero - 1; i++)printf("0");
printf("1\n");
continue;
}
int number, power;
if (s[len - 1] == '5') {
number = 2;
power = pw(5, len);
}
else {
number = 5;
power = pw(2, len);
}
memset(t, 0, sizeof(t));
t[1] = 1;
int high = 1;
int val;
for (int i = 1; i <= power; i++) {
high++;
val = 0;
for (int j = 1; j <= high; j++) {
val += t[j] * number;
t[j] = val % 10;
val = val / 10;
}
if (t[high] == 0)high--;
}
printf("0.");
for (int i = 0; i < zero; i++)printf("0");
zero = len - 1;
for (int i = 0; i < zero; i++)printf("0");
for (int i = high; i >= 1; i--)
printf("%d", t[i]);
printf("\n");
}
printf("End of problem 4 by team x\n");
return 0;
}