ZOJ1210毒瘤大整数幂乘题

此题巨坑!
题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/qq_43305312/article/details/109319753