POJ1001

C++源代码:

//	Exponentiation
//	copy


#include <iostream>

using namespace std;



// 计算 多 乘以 一 的情况,例如,1234 * 4

// many:    多位数

// one:        单位数

// offset:    乘10偏移

// return:    返回计算结果

char * MMO(char * many, char one, int offset)

{

	int mLength;    // 多位数的长度

	char * res;        // 计算结果

	int i;

	int n1, n2;        // 逐位相乘的两个乘数

	int sres;        // 逐位相乘的积

	int carry;        // 进位

					  // 初始化各变量

	n2 = one - 48;

	carry = 0;

	// 获取多位数的位数

	mLength = -1;

	while (many[++mLength]);

	// 计算运算结果的位数并分配空间

	res = new char[mLength + 1 + offset + 1];

	// 初始化结果为0

	for (i = 0; i < mLength + offset + 1; i++)

	{

		res[i] = '0';

	}

	res[mLength + offset + 1] = 0;    // 字符串结尾

									  // 逐位相乘

	for (i = mLength - 1; i >= 0; i--)

	{

		n1 = many[i] - 48;

		// 1. 将两个乘数相乘

		sres = n1 * n2;

		// 2. 将结果再加上进位

		sres += carry;

		// 3. 将计算得到的结果分成10进位和个位

		res[i + 1] = sres % 10 + 48;    // 个位,直接存在计算结果中

		carry = sres / 10;        // 十位,保存在进位中

	}

	// 将进位存入最高位

	res[0] = carry + 48;

	// 返回计算结果

	return res;

}



// 计算两个多位数相加,将结果存入m1,并释放m2

// m1:        多位数1

// m2:        多位数2

// 需要注意的是,多位数1的位数一定要大于等于两数和的位数

void MPM(char * m1, char * m2)

{

	int l1, l2;        // 两个多位数的长度

	char * res;        // 计算结果

	int i;

	int lRes;        // 结算结果的长度

	int carry;        // 进位

	int n1, n2;        // 两个单位加数位

					   // 初始化变量

	carry = 0;

	// 获取两个加数的长度

	l1 = l2 = -1;

	while (m1[++l1]);

	while (m2[++l2]);

	// 实现两数相加

	for (i = 1; i <= l1; i++)

	{

		n1 = m1[l1 - i] - 48;

		if (l2 - i < 0)

			n2 = 0;

		else

			n2 = m2[l2 - i] - 48;

		// 计算两数和并存入m1中

		m1[l1 - i] = (n1 + n2 + carry) % 10 + 48;

		carry = (n1 + n2 + carry) / 10;

	}

	// 将进位存入首位

	if (l1 != l2)

		m1[l1 - l2 - 1] = carry + 48;

	// 释放被加数

	delete m2;

}



// 计算两个多位数相乘

// m1:        乘数1

// m2:        乘数2

// return:    返回两数相乘结果

char * MMM(char * m1, char * m2)

{

	int l1, l2;        // 两个多位数的长度

	char * res;        // 计算结果

	int i;

	int lRes;        // 结算结果的长度

	int carry;        // 进位

	int n1, n2;        // 两个单位乘数位

					   // 初始化变量

	carry = 0;

	// 获取两个加数的长度

	l1 = l2 = 0;

	while (m1[l1++]);

	while (m2[l2++]);

	l1--;

	l2--;

	// 为了减少计算乘法次数,将位数较少的数作为乘数

	if (l1 < l2)

	{

		char * tp = m2;

		m2 = m1;

		m1 = tp;

		int tpl = l2;

		l2 = l1;

		l1 = tpl;

	}

	// 为计算结果分配空间

	// 两数相乘的结果的位数 = 被乘数的位数 + 乘数的位数

	lRes = l2 + l1;

	res = new char[lRes + 1];

	// 初始化结果为0

	for (i = 0; i < lRes; i++)

	{

		res[i] = '0';

	}

	res[lRes] = 0;

	// 进行逐位相乘

	for (i = 1; i <= l2; i++)

	{

		char * sr = MMO(m1, m2[l2 - i], i - 1);

		MPM(res, sr);

	}

	// 返回计算结果

	return res;

}



// 计算 R 的 N 次方,R和N均为整数

// return: 返回未修饰的计算结果

char * RN(char * R, int N)

{

	if (N < 2)

		return R;

	char * res = MMM(R, R);

	for (int i = 0; i < N - 2; i++)

	{

		char * res2 = res;

		res = MMM(res, R);

		delete res2;

	}

	return res;

}



// 规范化输出计算结果,加上小数点,并去掉多余的0

void OutputRes(char * res, int pNum)

{

	int lRes;

	int i;

	bool flag;

	// 获取输出字符串的长度

	lRes = -1;

	while (res[++lRes]);



	// 计算输出区间

	flag = false;

	if (pNum > 0)

	{

		// 过滤首尾不用输出的0

		for (i = 0; i < lRes - pNum; i++)

		{

			if (res[i] != '0')

				break;

			else

				res[i] = '#';

		}

		for (i = 1; i <= pNum; i++)

		{

			if (res[lRes - i] != '0')

				break;

			else

				res[lRes - i] = '#';

		}

		if (i > pNum)        // 小数部位不用输出

			flag = true;

	}
	else {

		flag = true;

		for (i = 0; i < lRes; i++)

		{

			if (res[i] != '0')

				break;

			else

				res[i] = '#';

		}

		for (i = 1; i <= lRes; i++)

		{

			if (res[lRes - i] != '0')

				break;

			else

				res[lRes - i] = '#';

		}

	}

	// 输出结果

	for (i = 0; i < lRes; i++)

	{

		if ((i == lRes - pNum) && (!flag))

			cout << ".";

		if (res[i] != '#')

		{

			cout << res[i];

		}



	}

	cout << endl;

}



int main() {

	char R[10], Rin[10];        // 读入的乘幂运算的底

	int N;            // 读入的乘幂运算的指数

	int pNum;        // 读入的小数位数

					 // 读入并计算

	while (cin >> Rin >> N)

	{

		// 获得小数点的位数,并获取去掉小数点后的整数

		int l;

		int ll;

		l = ll = 0;

		pNum = -1;

		while (Rin[l])

		{

			if (Rin[l] == '.')

			{

				pNum = l + 1;

			}
			else {

				R[ll++] = Rin[l];

			}

			l++;

		}

		R[ll] = 0;

		if (pNum != -1)

			pNum = l - pNum;

		else

			pNum = 0;

		pNum = pNum * N;

		// 计算并输出结果

		char * s = RN(R, N);

		OutputRes(s, pNum);

		if (s != R)

			delete s;

	}

	return 0;

}





  • 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、付费专栏及课程。

余额充值