poj1001

没事AA题 生活还不是美滋滋。很久没做ACM题目了,算不上老司机,纯粹打酱油。由于不喜欢写备注 发现很多题目自己曾经做过但再去看却没头绪,所以决定今后把解题报告写在博客上。养成写备注的好习惯
此题主要是细节处理需要注意。本人WA三次 第四次才AC
此题分为三个步骤
1.去小数点存储。
2.大数运算。
3.确定小数点位置,去前导0后导0。

#include<iostream>
#include "fstream"
using namespace std;
char str[7];
int n;
int pos = -1;
int res[150], a[150], b[7];
int j = 1;
int lena, lenb;
void multiply()//用来计算两个大数的乘法。
{
	int x = 1, y = 1;
	memset(res, 0, sizeof(res));      //用来保存a*b的结果
	for (int i = lenb; i >= 1; i--)
	{
		y = x;
		for (int k = lena; k >= 1; k--)
		{
			res[y] += a[k] * b[i];
			if (res[y] > 9)
			{
				res[y + 1] += res[y] / 10; 
				res[y] = res[y] % 10;
			}
			y++;

		}
		x++;
	}
	if (res[lena + lenb] > 0)//判断大数运算后的长度保存在lena 因为后续会把res结果赋值给a 
	{
		lena = lenb + lena;
	}
	else
	{
		lena = lena + lenb - 1;
	}
	for (int i = 1; i <= lena; i++)
	{
		a[lena + 1 - i] = res[i];    //计算完毕一次后把 res结果赋值给a ,这里我反向了,因为计算结果算出来的是反向的,必须正常化
	}
}
int main()
{
	//ifstream cin("Text.txt");
	while (cin >> str >> n)
	{
		pos = -1;
		j = 1;
		for (int i = 0; i < 6; i++)
		{
			if (str[i] == '.')
			{
				pos = 5 - i;
			}
			else
			{
				b[j] = a[j++] = str[i] - '0';
			}
		}
		if (pos == -1)                //如果没有小数点的话即 lena保存的是6位数 的长度是6.
		{
			lena = lenb = 6;
		}
		else                         //否则a里面保存的数字是除去小数点以外的5位
		{
			lenb = lena = 5;
		}
		if (a[3] == 0 && a[1] == 0 && a[2] == 0 && a[4] == 0 && a[5] == 0 && a[6] == 0) //极端情况 如果输入时.00000即可1直接输出
		{
			cout << 0 << endl;
			continue;;
		}
		for (int i = 1; i <= n - 1; i++)   //大数相乘
		{
			multiply();
		}

		if (n == 1)                       //如果n==1只需要清除前导0和后导0;
		{
			int m = 1;
			while (a[m] == 0 && (6 - pos) > m)m++;//清除前导0;
			while (a[lena] == 0 && pos != -1 && lena >= 6 - pos)lena--;//清除后导0;
			for (int i = m; i <= lena; i++)//输出
			{
				if (i == (6 - pos))
				{
					cout << '.';
				}
				cout << a[i];
			}
			cout << endl;
		}
		else if (pos == -1)//若没有小数点 计算出来的数不必处理直接输出 
		{
			for (int i = lena; i >= 1; i--)
			{
				cout << res[i];
			}
			cout << endl;
		}
		else
		{
			pos *= n;//小数点位置
			int m = 1;
			while (res[m] == 0 && m <= pos)m++;//去后导
			if (res[lena] == 0)lena--;         //去前导
			for (int i = lena; i >= m; i--)   //运算的结果是反向的所以要反向输出。
			{
				if (i == pos)
				{
					cout << '.';
				}
				cout << res[i];
			}
			cout << endl;
		}
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
	}

	return 0;
}
附上测试用例
input
99.001  3
99.010  1
99.010  3
99.100  1
99.100  3
95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12
.00001  1
.12345  1
0001.1  1
1.1000  1
10.000  1
000.10  1
000010  1
000.10  1
0000.1  1
00.111  1
0.0001  1
0.0001  3
0.0010  1
0.0010  3
0.0100  1
0.0100  3
0.1000  1
0.1000  3
1.0000  1
1.0000  3
1.0001  1
1.0001  3
1.0010  1
1.0010  3
1.0100  1
1.0100  3
1.1000  1
1.1000  3
10.000  1
10.000  3
10.001  1
10.001  3
10.010  1
10.010  3
10.100  1
10.100  3
99.000  1
99.000  3
99.001  1
99.001  3
99.010  1
99.010  3
99.100  1
99.100  3
99.998  1
99.998  3
95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12
.00001  1
.12345  1
0001.1  1
1.1000  1
10.000  1
000.10  1
000010  1
000.10  1
0000.1  1
00.111  1
0.0001  1
0.0001  3
0.0010  1
0.0010  3
0.0100  1
0.0100  3
0.1000  1
0.1000  3
1.0000  1
1.0000  3
1.0001  1
1.0001  3
1.0010  1
1.0010  3
1.0100  1
1.0100  3
1.1000  1
1.1000  3
10.000  1
10.000  3
10.001  1
10.001  3
10.010  1
10.010  3
10.100  1
10.100  3
99.000  1
99.000  3
99.001  1
99.001  3
99.010  1
99.010  3
99.100  1
99.100  3
99.998  1
99.998  3
10.100  1
10.100  3
99.000  1
99.000  3
99.001  1
99.998  1
3.0000  2
0.0000  3

output
970328.403297001
99.01
970593.059701
99.1
973242.271
548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
.00001
.12345
1.1
1.1
10
.1
10
.1
.1
.111
.0001
.000000000001
.001
.000000001
.01
.000001
.1
.001
1
1
1.0001
1.000300030001
1.001
1.003003001
1.01
1.030301
1.1
1.331
10
1000
10.001
1000.300030001
10.01
1003.003001
10.1
1030.301
99
970299
99.001
970328.403297001
99.01
970593.059701
99.1
973242.271
99.998
999940.001199992
548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
.00001
.12345
1.1
1.1
10
.1
10
.1
.1
.111
.0001
.000000000001
.001
.000000001
.01
.000001
.1
.001
1
1
1.0001
1.000300030001
1.001
1.003003001
1.01
1.030301
1.1
1.331
10
1000
10.001
1000.300030001
10.01
1003.003001
10.1
1030.301
99
970299
99.001
970328.403297001
99.01
970593.059701
99.1
973242.271
99.998
999940.001199992
10.1
1030.301
99
970299
99.001
99.998
9
0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值