POJ 1001

题意: 实数的n次幂。如果小于0,小数点前的0不用输出。

算法: 1.输入(底数当做字符串来处理, 指数直接int输入)

     2.记录小数点位数,删除小数点

     3.将底数由char[] ——>int[],并且颠倒数字顺序。如:“95.123”——>{3, 2, 1, 5, 9}.同时获取底数的位数

     4.计算n次幂

     5.输出。

    细化: 1、2、3步没有什么要注意的。  主要在第四步:

 4.a.要注意是进行n-1次乘法。 

    b.存在数组里的数可能会溢出, 及时做进位处理

    c.每次乘积的结果要重新计算它的位数。 我一开始天真的以为每次位数增加 (bits_lead - 1)位, 一直得不到结果。

5.a.输出时注意要去除前缀零 和 后缀零

    b.小数点根据一开始记录的小数点位数来输出


代码:

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

#define MAX_OUT_BITS 100
#define MAX_IN_BITS 30

int bits_lead, bits_zero_point,int_lead[MAX_IN_BITS];
int result[MAX_OUT_BITS], tmp_result[MAX_OUT_BITS];
char ch_lead[MAX_IN_BITS];
int int_index;

int toDigit(void);		//转换成int的函数
void toPow(void);
void toPrint(void);
void toTen(int *);		//进位函数
void toMultiply(int *, int *);

int main() {
	char *p;

	while (scanf("%s%d", ch_lead, &int_index) != EOF) {

		for (p = ch_lead; *p != '.'; p++) {
		}
		bits_zero_point = strlen(p) - 1; 
		strcpy(p, p + 1);			//delete '.'

		bits_lead = toDigit();
		toPow();
		toPrint();
	}

	return 0;
}

/****************************************************************************
 * toDigit(): num(char) to num(int) and transpos num sort
 ***************************************************************************/
int toDigit(void) {
	int bits;
	int i, j;
	
	memset(int_lead, 0, sizeof(int_lead));
	bits = strlen(ch_lead);
	for (i = 0, j = bits - 1; i < bits; i++, j--) {
		int_lead[j] = (int)(ch_lead[i] - '0');
	}

	return bits;
}

/************************************************************************
 * toPow():
 * *********************************************************************/
void toPow(void) {
	int i, j, k, l;
	int change[MAX_OUT_BITS];

	int_index--;			//进行int_index次乘法

	memset(result, 0, sizeof(result));
	for (i = 0; i < bits_lead; i++) {
		result[i] = int_lead[i];
	}

	for (i = 0; i < int_index; i++){

		//translate result to change
		for (j = 0; j < MAX_OUT_BITS; j++) {
			change[j] = result[j];
		}
		
		toMultiply(change, int_lead);
		toTen(result);				//及时进位
	}
}

/************************************************************************
 * toTen():
 * *********************************************************************/
void toTen(int *num) { 
	int tmp;

	for (int i = 0; i < MAX_OUT_BITS; i++) {
		tmp = num[i] / 10;
		num[i] = num[i] % 10;
		num[i + 1] += tmp;
	}
}

/*************************************************************************
 * toMultiply():
 * **********************************************************************/
void toMultiply(int *change, int *lead) {
	int chg_bits;

	//get chg_bits(重新统计位数)
	for (int i = MAX_OUT_BITS - 1; i >= 0; i--) {
		if (change[i] != 0) {
			chg_bits = i + 1;
			break;
		}
	}

	memset(result, 0, sizeof(result));	

	for (int i = 0; i < chg_bits; i++) {
		for (int j = 0; j < bits_lead; j++) {
			result[i + j] += change[i] * lead[j];
		}
	}
}




/*************************************************************************
 * toPrint()
 ************************************************************************/
void toPrint(void) {
	int mark_head = 0, mark_tail = 0, i;
	int num_point;
	num_point = bits_zero_point * (int_index + 1);

	//去除后缀零
	for (i = 0; i < MAX_OUT_BITS; i++) {
		if (result[i] != 0) {
			mark_tail = i;
			break;
		}
	}
	for (i = (MAX_OUT_BITS - 1); i >= mark_tail ; i--) {
		if (result[i] != 0) {			//去除前缀零
			mark_head = 1;
		}

		if (i == num_point - 1){		//打印小数点
			printf(".");
			mark_head = 1;
		}

		if (mark_head == 1) {
			printf("%d", result[i]);
		}

	}

	printf("\n");

}


教训:1.算法的核心部分(toPow())写得不清不楚就直接开始敲代码。 结果各种错。

   2.不踏实, 太急功近利。 不过到最后一天表现不错, 很有耐心。(这道题我卡了3天, toPow()函数。快哭了)。其实耐心一点,第一天就能解决掉的。

   3.少用全局变量。 函数接口化。 这是很值得去做的。 重写toPow(), 加入一个toMultiply(int *, int *, int *)函数。 result[] 已经定义为全局变量了, 但是我却把它作为函数参数, 在函数中用memset(result, 0, sizeof(result)); 结果只有result[0] 被清为零。 因为这里的result是局部int指针变量, 并非数组指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems. This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25. 输入说明 The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9. 输出说明 The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer. 输入样例 95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12 输出样例 548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201 小提示 If you don't know how to determine wheather encounted the end of input: s is a string and n is an integer C++ while(cin>>s>>n) { ... } c while(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want /*while(scanf(%s%d",s,&n)!=EOF) //this also work */ { ... } 来源 East Central North America 1988 北大OJ平台(代理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值