现在的位置: 首页 > 综合 > 正文

HDOJ 1063 Exponentiation

2013年05月30日 ⁄ 综合 ⁄ 共 2547字 ⁄ 字号 评论关闭

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1063

 

题目大意:求R(0.0<R<99.999)的n(0 < n <= 25)次方。

 

分析题意:

此题一看便知道是关于大数乘法的问题,属于比较常见的问题。我的解题思路是这样的:先将浮点数乘法转化为正整数乘法,然后再加小数点

1、   将输入的R从浮点数转换成正整数,并记录下小数位数。

2、   于是此题就转变为大数整数乘法,大数整数乘法就不具体说了,具体见代码,值得一提的是,本题中的乘法的最小乘数为6位数乘6位数,所以需要用__64int 数据类型。

3、   最后获得正整数的乘积,在根据情况,添加小数点,具体见代码。

 

题外话:此题本来思路挺简单,但由于自己太菜,出现了诸多细节问题,导致纠结了很久:

1、   最开始没有使用__64int 数据类型,调试半天才发现用int类型6位数乘6位数根本不够。

2、   这个语句:printf("%0*d", s, res[i]/ (pow(10.0,9-s)));

错了半天一直没有发现(pow(10.0,9-s))的结果为浮点数,如果不转为整数,做除法后结果依然为浮点数,会导致输出错误。正确的应当是这样:

printf("%0*d", s, res[i]/(int)(pow(10.0,9-s)));

3、   此题,最后输出是关键,一定要充分考虑个各种情况,例如:存结果的数组的第一个数的输出方式应该与后面的数的输出方式不同。第一个数可以直接输出,而后面的数一定要考虑0的个数,例如本来一个数是:10003,假如结果数组每个数都为4位数,则res[0] = 1,res[1] = 3,这时res[0]可以直接输出,而res[1]必须这样输出:printf(“%04d”, res[1]);,因为这样res[1]才会输出:0003。

 

Ps:刚刚不小心去看了下此题的数据统计,竟然发现我排在了第二,第一次这么靠前,实在是运气不错啊!贴个图纪念下!

 

#include<stdio.h>
#include<string.h>
#include<math.h>

#define MAX 1000000000

int myPower(int num, __int64 res[], int n)
{
	int c, i, j, t;
	
	for(i=1; i<25; i++){
		res[i] = 0;
	}
	res[0] = 1;
	t = 0;
	for(i=0; i<n; i++){
		c = 0;
		for(j=0; j<=t; j++){
			res[j] = num * res[j] + c;
			c = res[j] / MAX;
			res[j] = res[j] % MAX;
		}
		if(c > 0){
			t++;
			res[t] = c;
		}
	}
	return t;
}

int findPointAndTransform(char a[], int *num)
{
	int i, j, res, decimalPos, a_len;
	j = 0;
	res = 0;
	a_len = strlen(a);
	decimalPos = 0;
	for(i=a_len-1; i>=0; i--){
		if(a[i] != '.'){
			res+=(a[i]-'0')*(pow(10.0, j));
			j++;
		}
		else{
			decimalPos = j;
		}
	}
	i=1;
	j = res % ((int)pow(10.0, i));
	while(j==0){
		if((decimalPos-i+1) <= 0){
			break;
		}
		i++;
		j = res % ((int)pow(10.0, i));
	}

	*num = res/((int)pow(10.0,i-1));
	
	return decimalPos-i+1;
}

int main()
{
	char r[10];
	__int64 res[25];
	int num = 0;
	int decimalPos;
	int resAmount;
	int n, t, i, j, p, k, s;

	while(scanf("%s%d", r, &n) != EOF){

		decimalPos =  findPointAndTransform(r, &num);  //将小数转化为整数,并记录小数位数
		t = myPower(num, res, n);  //计算结果保存在res中
		
		resAmount = t * 9; //计算最后的结果的位数
		j = 1;                        
		while((res[t]/((int)pow(10.0, j))) >= 1){
			j++;
		}
		resAmount+=j;
		p = (decimalPos*n)-resAmount;
		if(decimalPos == 0){
			printf("%d", res[t]);
			for(i=t-1; i>=0; i--){
				printf("%09d", res[i]);
			}
		}
		else if(n == 0){
			printf("1");
		}
		else if(p >= 0){
			printf(".");
			for(i=p; i>0; i--){
				printf("0");
			}
			printf("%d", res[t]);
			for(i=t-1; i>=0; i--){
				printf("%09d", res[i]);
			}
		}
		else{
			p = abs(p);
			if(p < j){
				printf("%d", res[t]/(int)(pow(10.0,j-p)));
				printf(".");
				printf("%0*d", j-p, res[t] %(int)(pow(10.0,j-p)));
				for(i=t-1; i>=0; i--){
					printf("%09d", res[i]);
				}
			}
			else if(p == j){
				printf("%d", res[t]);
				printf(".");
				for(i=t-1; i>=0; i--){
					printf("%09d", res[i]);
				}
			}
			else{
				printf("%d", res[t]);
				k = (p - j) / 9;
				s = (p - j) % 9;
				i = t-1;
				for(i; i>t-1-k; i--){
					printf("%09d", res[i]);
				}
				if(s != 0){
					printf("%0*d", s, res[i]/(int)(pow(10.0,9-s)));
				}
				printf(".");
				printf("%0*d",9-s, res[i] % (int)(pow(10.0,9-s)));
				for(i=i-1; i>=0; i--){
					printf("%09d", res[i]);
				}
			}
		}
		printf("\n");
	}
	return 0;
}

抱歉!评论已关闭.