Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Problem 1001 ask for help

Posted by philia2008 at 2008-06-27 16:38:34 and last updated at 2008-06-27 16:39:39
i have tested all the numbers on this board, the results seem all right.
but still get WA.
don't know why.....thx for your help~~

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
//	大数的定义, 两个字符串数组, 整数部分从左向右分个位->十位->百位, 小数部分也是从左向右
//	这样设计的原因是因为做加法的时候需要开辟新的内存, 而realloc的内存是接在后面的, 一般加过之后
//	的结果都溢出在前面
typedef struct BigNum
{
	unsigned char* INTEGER;
	unsigned char* NUMERIC;
}BM;
//	大数初始化
BM* BM_init(char* str)
{
	int iInputLength = strlen(str);
	//	开辟新的大数空间
	BM* new_BM = (BM*)malloc(sizeof(BM));
	//memset(new_BM, 0, sizeof(BM));
	//	开辟缓冲区
	char* buffer = (char*)malloc(iInputLength + 1);
	//memset(buffer, 0, iInputLength + 1);
	for (char* p = buffer; p != buffer + iInputLength + 1; p++)
	{
		*p = 0;
	}
	//	拷贝
	strcpy(buffer, str);
	//	查找小数点
	char* pchDot = strchr(buffer, '.');

	int iIntLength = pchDot - buffer;
	int iNumericLength = buffer + strlen(buffer) - pchDot - 1;

	new_BM->INTEGER = (unsigned char*)malloc(iIntLength + 1);
	//memset(new_BM->INTEGER, 0, iIntLength + 1);
	for (unsigned char* p = new_BM->INTEGER; p != new_BM->INTEGER + iIntLength + 1; p++)
	{
		*p = 0;
	}
	new_BM->NUMERIC = (unsigned char*)malloc(iNumericLength + 1);
	//memset(new_BM->NUMERIC, 0, iNumericLength + 1);	
	for (unsigned char* p = new_BM->NUMERIC; p != new_BM->NUMERIC + iNumericLength + 1; p++)
	{
		*p = 0;
	}

	//	赋初值
	strncpy((char*)new_BM->INTEGER, buffer, iIntLength);
	strcpy((char*)new_BM->NUMERIC, pchDot + 1);

	//	整数部分反序
	for (int i=0; i < iIntLength/2; i++)
	{
		unsigned char chTemp = new_BM->INTEGER[i];
		new_BM->INTEGER[i] = new_BM->INTEGER[iIntLength - i - 1];
		new_BM->INTEGER[iIntLength - i - 1] = chTemp;
	}

	free(buffer);
	return new_BM;
}
//	销毁大数
void BM_free(BM* bm)
{
	if (bm->INTEGER)
	{
		free(bm->INTEGER);
		bm->INTEGER = NULL;
	}
	if (bm->NUMERIC)
	{
		free(bm->NUMERIC);
		bm->NUMERIC = NULL;
	}
	if (bm)
	{
		free(bm);
		bm = NULL;
	}
}
//	两个字符相加
unsigned char BM_chAdd(unsigned char ch1, unsigned char ch2)
{
	if (ch1 > '9')
	{
		ch1 = ch1 - 'A' + 10;
	}
	else
	{
		ch1 = ch1 - '0';
	}
	if (ch2 > '9')
	{
		ch2 = ch2 - 'A' + 10;
	}
	else
	{
		ch2 = ch2 - '0';
	}
	unsigned char sum = ch1 + ch2;
	if (sum > 9)
	{
		sum = sum + 'A' - 10;
	}
	else
	{
		sum = sum + '0';
	}
	return sum;
}
//	两个字符相乘
unsigned char BM_chMul(unsigned char ch1, unsigned char ch2)
{
	if (ch1 > '9')
	{
		ch1 = ch1 - 'A' + 10;
	}
	else
	{
		ch1 = ch1 - '0';
	}
	if (ch2 > '9')
	{
		ch2 = ch2 - 'A' + 10;
	}
	else
	{
		ch2 = ch2 - '0';
	}
	unsigned char sum = ch1 * ch2;
	if (sum > 9)
	{
		sum = sum + 'A' - 10;
	}
	else
	{
		sum = sum + '0';
	}
	return sum;
}
//	调整进位
void BM_Adjust(BM* bm)
{
	//	小数部分处理
	//	小数部分应该从右向左处理
	for (unsigned int j=strlen((char*)bm->NUMERIC) - 1; j > 0; j--)
	{
		if (bm->NUMERIC[j] > '9')
		{
			bm->NUMERIC[j-1] = BM_chAdd(bm->NUMERIC[j-1], (bm->NUMERIC[j] - 'A') / 10 + '1');
			bm->NUMERIC[j] = (bm->NUMERIC[j] - 'A') % 10 + '0';
		}
	}
	//	小数部分向整数部分过渡
	if (bm->NUMERIC[0] > '9')
	{
		bm->INTEGER[0] = BM_chAdd(bm->INTEGER[0], (bm->NUMERIC[0] - 'A') / 10 + '1');
		bm->NUMERIC[0] = (bm->NUMERIC[0] - 'A') % 10 + '0';
	}
	//	整数部分处理
	for (unsigned int i=0; i < strlen((char*)bm->INTEGER) - 1; i++)
	{
		if (bm->INTEGER[i] > '9')
		{
			bm->INTEGER[i+1] = BM_chAdd(bm->INTEGER[i+1], (bm->INTEGER[i] - 'A') / 10 + '1');
			bm->INTEGER[i] = (bm->INTEGER[i] - 'A') % 10 + '0';
		}
	}
	//	最高位
	int iOldIntLength = strlen((char*)bm->INTEGER);
	if (bm->INTEGER[iOldIntLength - 1] > '9')
	{
		//	溢出
		bm->INTEGER = (unsigned char*)realloc(bm->INTEGER, iOldIntLength + 2);
		bm->INTEGER[iOldIntLength + 1] = 0;
		//	进位是除以10
		bm->INTEGER[iOldIntLength] = (bm->INTEGER[iOldIntLength - 1] - 'A') / 10 + '1';
		bm->INTEGER[iOldIntLength - 1] = bm->INTEGER[iOldIntLength - 1] - 'A' + '0';
	}
}
//	大数字符串相加
unsigned char* BM_strAdd(unsigned char* str1, unsigned char* str2)
{
	unsigned char* str;
	//	按较长的str开辟内存
	int iLength1 = strlen((char*)str1);
	int iLength2 = strlen((char*)str2);
	int iMaxLength;
	if (iLength1 > iLength2)
	{
		str = (unsigned char*)malloc(iLength1 + 1);
		//memset(str, 0, iLength1 + 1);
		for (unsigned char* p = str; p != str + iLength1 + 1; p++)
		{
			*p = 0;
		}
		iMaxLength = iLength1;
	}
	else
	{
		str = (unsigned char*)malloc(iLength2 + 1);
		//memset(str, 0, iLength2 + 1);
		for (unsigned char* p = str; p != str + iLength2 + 1; p++)
		{
			*p = 0;
		}
		iMaxLength = iLength2;
	}
	unsigned char* pchStr1 = str1;
	unsigned char* pchStr2 = str2;
	unsigned char* pchStr = str;

	for (int i=0; i < iMaxLength; i++, pchStr1++, pchStr2++, pchStr++)
	{
		unsigned char chNum1, chNum2;
		if (pchStr1 < str1 + iLength1)
		{
			chNum1 = *pchStr1;
		}
		else
		{
			chNum1 = '0';
		}
		if (pchStr2 < str2 + iLength2)
		{
			chNum2 = *pchStr2;
		}
		else
		{
			chNum2 = '0';
		}
		*pchStr = BM_chAdd(chNum1, chNum2);
	}
	return str;
}
//	大数加法
BM* BM_Add(BM* bm1, BM* bm2)
{
	BM* new_BM = (BM*)malloc(sizeof(BM));
	//memset(new_BM, 0, sizeof(BM));
	//	计算unsigned char*的加法
 	new_BM->INTEGER = BM_strAdd(bm1->INTEGER, bm2->INTEGER);
 	new_BM->NUMERIC = BM_strAdd(bm1->NUMERIC, bm2->NUMERIC);
	//	处理进位
	BM_Adjust(new_BM);
	return new_BM;
}
//	大数乘法
BM* BM_Mul(BM* bm1, BM* bm2)
{
	BM* new_BM = (BM*)malloc(sizeof(BM));
	//memset(new_BM, 0, sizeof(BM));
	//	先写小数部分的乘法, 小数部分*小数部分
	//	开辟小数乘法结果的内存区, 0.123 * 0.4567 = 0.0561741
	//	也就是说两个小数部分的精度位数相加, 就等于结果的精度, 也就是结果的位数
	int iNumericLength1 = strlen((char*)bm1->NUMERIC);
	int iNumericLength2 = strlen((char*)bm2->NUMERIC);
	int iNumericLength = iNumericLength1 + iNumericLength2;
	new_BM->NUMERIC = (unsigned char*)malloc(iNumericLength + 1);
	//memset(new_BM->NUMERIC, '0', iNumericLength);
	for (unsigned char* p = new_BM->NUMERIC; p != new_BM->NUMERIC+iNumericLength; p++)
	{
		*p = '0';
	}
	new_BM->NUMERIC[iNumericLength] = 0;
	//	为了避免adjust出错, 这里先初始化整数部分
	int iIntLength1 = strlen((char*)bm1->INTEGER);
	int iIntLength2 = strlen((char*)bm2->INTEGER);
	int iIntLength = iIntLength1 + iIntLength2;
	new_BM->INTEGER	= (unsigned char*)malloc(iIntLength + 1);
	//memset(new_BM->INTEGER, '0', iIntLength);
	for (unsigned char* p=new_BM->INTEGER; p != new_BM->INTEGER+iIntLength; p++)
	{
		*p = '0';
	}
	new_BM->INTEGER[iIntLength] = 0;

	//	三个指针都指向最后一位
	unsigned char* pchNumeric1 = bm1->NUMERIC + iNumericLength1 - 1;
	unsigned char* pchNumeric2 = bm2->NUMERIC + iNumericLength2 - 1;
	unsigned char* pchNumeric = new_BM->NUMERIC + iNumericLength - 1;

	while (pchNumeric1 != bm1->NUMERIC - 1)
	{
		pchNumeric2 = bm2->NUMERIC + iNumericLength2 - 1;
		unsigned char* pchNumericTemp = pchNumeric;
		while (pchNumeric2 != bm2->NUMERIC - 1)
		{
			*pchNumericTemp = BM_chAdd(*pchNumericTemp, BM_chMul(*pchNumeric1, *pchNumeric2));
			BM_Adjust(new_BM);
			pchNumericTemp--;
			pchNumeric2--;
		}
		pchNumeric1--;
		pchNumeric--;
	}
	//	整数部分的处理, 整数部分*整数部分
	//	处理方法基本上同小数部分, 稍有不同的地方是整数部分是个位在左边, 所以是从左向右计算
	unsigned char* pchInt1 = bm1->INTEGER;
	unsigned char* pchInt2 = bm2->INTEGER;
	unsigned char* pchInt = new_BM->INTEGER;

	while (pchInt1 != bm1->INTEGER + iIntLength1)
	{
		pchInt2 = bm2->INTEGER;
		unsigned char* pchIntTemp = pchInt;
		while (pchInt2 != bm2->INTEGER + iIntLength2)
		{
			*pchIntTemp = BM_chAdd(*pchIntTemp, BM_chMul(*pchInt1, *pchInt2));
			BM_Adjust(new_BM);
			pchIntTemp++;
			pchInt2++;
		}
		pchInt1++;
		pchInt++;
	}

	//	最难的部分在这里, 也就是整数部分*小数部分+小数部分*整数部分
	unsigned char* pchDiffInt1 = bm1->INTEGER;
	unsigned char* pchDiffInt2 = bm2->INTEGER;
	unsigned char* pchDiffInt = new_BM->INTEGER;
	unsigned char* pchDiffNumeric1 = bm1->NUMERIC + iNumericLength1 - 1;
	unsigned char* pchDiffNumeric2 = bm2->NUMERIC + iNumericLength2 - 1;
	unsigned char* pchDiffNumeric = new_BM->NUMERIC + iNumericLength2 - 1;

	//	先算1的整数部分*2的小数部分
	while (pchDiffNumeric2 != bm2->NUMERIC - 1)
	{
		pchDiffInt1 = bm1->INTEGER;
		unsigned char* pchIntTemp = pchDiffInt;
		unsigned char* pchNumericTemp = pchDiffNumeric;
		while (pchDiffInt1 != bm1->INTEGER + iIntLength1)
		{
			if (pchNumericTemp < new_BM->NUMERIC)
			{
				//	往整数部分放
				*pchIntTemp = BM_chAdd(*pchIntTemp, BM_chMul(*pchDiffInt1, *pchDiffNumeric2));
				BM_Adjust(new_BM);
				pchDiffInt1++;
				pchIntTemp++;
			}
			else
			{
				*pchNumericTemp = BM_chAdd(*pchNumericTemp, BM_chMul(*pchDiffInt1, *pchDiffNumeric2));
				BM_Adjust(new_BM);
				pchDiffInt1++;
				pchNumericTemp--;
			}
		}
		pchDiffNumeric2--;
		pchDiffNumeric--;
	}

	//	再算2的整数部分*1的小数部分
	pchDiffInt1 = bm1->INTEGER;
	pchDiffInt2 = bm2->INTEGER;
	pchDiffInt = new_BM->INTEGER;
	pchDiffNumeric1 = bm1->NUMERIC + iNumericLength1 - 1;
	pchDiffNumeric2 = bm2->NUMERIC + iNumericLength2 - 1;
	pchDiffNumeric = new_BM->NUMERIC + iNumericLength1 - 1;

	while (pchDiffNumeric1 != bm1->NUMERIC - 1)
	{
		pchDiffInt2 = bm2->INTEGER;
		unsigned char* pchIntTemp = pchDiffInt;
		unsigned char* pchNumericTemp = pchDiffNumeric;
		while (pchDiffInt2 != bm2->INTEGER + iIntLength2)
		{
			if (pchNumericTemp < new_BM->NUMERIC)
			{
				*pchIntTemp = BM_chAdd(*pchIntTemp, BM_chMul(*pchDiffInt2, *pchDiffNumeric1));
				BM_Adjust(new_BM);
				pchDiffInt2++;
				pchIntTemp++;
			}
			else
			{
				*pchNumericTemp = BM_chAdd(*pchNumericTemp, BM_chMul(*pchDiffInt2, *pchDiffNumeric1));
				BM_Adjust(new_BM);
				pchDiffInt2++;
				pchNumericTemp--;
			}
		}
		pchDiffNumeric1--;
		pchDiffNumeric--;
	}

	BM_Adjust(new_BM);
	return new_BM;
}
//	打印大数
void BM_print(BM* bm)
{
	int iIntLength = strlen((char*)bm->INTEGER);
	unsigned char* buffer = (unsigned char*)malloc(iIntLength + 1);
	//memset(buffer, 0, iIntLength + 1);
	for (unsigned char* p=buffer; p != buffer + iIntLength + 1; p++)
	{
		*p = 0;
	}
	strcpy((char*)buffer, (char*)bm->INTEGER);
	//	反序, 为了打印出正确的结果而反序
	//	这个反序的字符串是新开辟的, 并不会影响原来大数里面的顺序
	for (int i=0; i < iIntLength/2; i++)
	{
		unsigned char chTemp = buffer[i];
		buffer[i] = buffer[iIntLength - i - 1];
		buffer[iIntLength - i - 1] = chTemp;
	}
	//	打印
	//	整数部分前面的0忽略
	int iIntStart = strlen((char*)buffer);
	for (unsigned int j=0; j < strlen((char*)buffer); j++)
	{
		if ('0' == buffer[j])
		{

		}
		else
		{
			iIntStart = j;
			break;
		}
	}
	if (strlen((char*)buffer) == (unsigned int)iIntStart)
	{
		//	整数部分为0
		iIntStart--;
	}
	//	不显示小数部分后面的0
	int iNumericEnd = 0;
	for (unsigned int k = strlen((char*)bm->NUMERIC) - 1; k >= 0; k--)
	{
		if ('0' == bm->NUMERIC[k])
		{

		}
		else
		{
			iNumericEnd = k;
			break;
		}
	}
	unsigned char* buffer_numeric = NULL;
	if (-1 == iNumericEnd)
	{
		//	说明小数部分全是0了
	}
	else
	{
		buffer_numeric = (unsigned char*)malloc(iNumericEnd + 2);
		//memset(buffer_numeric, 0, iNumericEnd + 2);
		for (unsigned char* p = buffer_numeric; p != buffer_numeric + iNumericEnd + 2; p++)
		{
			*p = 0;
		}
		strncpy((char*)buffer_numeric, (char*)bm->NUMERIC, iNumericEnd + 1);
	}
	if ('0' == buffer[iIntStart] && -1 == iNumericEnd)
	{
		//	整数部分小数部分都是0
		//printf("0.0\n");
		printf("0\n");
	}
	else if ('0' == buffer[iIntStart] && -1 != iNumericEnd)
	{
		//	说明整数部分为0, 则直接显示小数部分即可
		printf(".%s\n", buffer_numeric);
	}
	else if ('0' != buffer[iIntStart] && -1 == iNumericEnd)
	{
		//	小数部分全为0, 说明是整数
		printf("%s\n", buffer + iIntStart);
	}
	else
	{
		//	整数部分小数部分都不是0
		printf("%s.%s\n", buffer + iIntStart, buffer_numeric);
	}
	free(buffer);
	buffer = NULL;
	free(buffer_numeric);
	buffer_numeric = NULL;
}

#define MAXOFNUMBER 6
#define NUMLENTH 10

int main()
{
	char strInput[MAXOFNUMBER][NUMLENTH] = {0};
	int n[MAXOFNUMBER];

	//memset(strInput, 0, MAXOFNUMBER*10);
	for (int j=0; j < MAXOFNUMBER; j++)
	{
		scanf("%s %d", strInput[j], &n[j]);
	}

	for (int k=0; k < MAXOFNUMBER; k++)
	{
		if ('.' == strInput[k][0])
		{
			//	只有小数部分
			//	是否全是0?
			int ibIsNULL = 1;
			for (int ib=1; ib < strlen(strInput[k]); ib++)
			{
				if (strInput[k][ib] != '0')
				{
					ibIsNULL = 0;
					break;
				}
			}
			if (0 == ibIsNULL)
			{
				//	是否是0次方?或1次方?
				if (0 == n[k])
				{
					printf("1\n");
				}
				else if (1 == n[k])
				{
					char* temp = (char*)malloc(strlen(strInput[k]) + 2);
					//memset(temp, 0, strlen(strInput[k]) + 2);
					for (char* p = temp; p != temp + strlen(strInput[k]) + 2; p++)
					{
						*p = 0;
					}
					sprintf(temp, "%s%s", "0", strInput[k]);

					BM* bm1 = BM_init(temp);
					BM_print(bm1);
					BM_free(bm1);
				}
				else
				{
					char* strTemp = (char*)malloc(strlen(strInput[k]) + 2);
					//memset(strTemp, 0, strlen(strInput[k]) + 2);
					for (char* p = strTemp; p != strTemp + strlen(strInput[k]) + 2; p++)
					{
						*p = 0;
					}
					sprintf(strTemp, "%s%s", "0", strInput[k]);

					BM* bm1 = BM_init(strTemp);
					BM* bm2 = BM_init(strTemp);
					BM* bmResult = bm1;
					free(strTemp);
					for (int i=0; i <n[k] - 1; i++)
					{
						BM* temp = bmResult;
						bmResult = BM_Mul(bmResult, bm2);
						BM_free(temp);
					}
					BM_print(bmResult);
					BM_free(bmResult);
					BM_free(bm2);
				}
			}
			else
			{
				//	全是0
				if (0 == n[k])
				{
					printf("1\n");
				}
				else
				{
					//printf("0.0\n");
					printf("0\n");
				}
			}
		}
		else if (NULL == strchr(strInput[k], '.'))
		{
			//	没输入小数点?只有整数部分?
			//	同样需要判断是否全是0?
			int ibIsNULL = 1;
			for (int ib=0; ib < strlen(strInput[k]); ib++)
			{
				if (strInput[k][ib] != '0')
				{
					ibIsNULL = 0;
					break;
				}
			}
			if (0 == ibIsNULL)
			{
				if (0 == n[k])
				{
					printf("1\n");
				}
				else if (1 == n[k])
				{
					char* temp = (char*)malloc(strlen(strInput[k]) + 3);
					//memset(temp, 0, strlen(strInput[k]) + 3);
					for (char* p = temp; p != temp + strlen(strInput[k]) + 3; p++)
					{
						*p = 0;
					}
					strcpy(temp, strcat(strInput[k], ".0"));

					BM* bm1 = BM_init(temp);
					BM_print(bm1);
					BM_free(bm1);
				}
				else
				{
					char* strTemp = (char*)malloc(strlen(strInput[k]) + 3);
					//memset(strTemp, 0, strlen(strInput[k]) + 3);
					for (char* p = strTemp; p != strTemp + strlen(strInput[k]) + 3; p++)
					{
						*p = 0;
					}
					strcpy(strTemp, strcat(strInput[k], ".0"));

					BM* bm1 = BM_init(strTemp);
					BM* bm2 = BM_init(strTemp);
					BM* bmResult = bm1;
					free(strTemp);
					for (int i=0; i <n[k] - 1; i++)
					{
						BM* temp = bmResult;
						bmResult = BM_Mul(bmResult, bm2);
						BM_free(temp);
					}
					BM_print(bmResult);
					BM_free(bmResult);
					BM_free(bm2);
				}
			}
			else
			{
				//printf("0.0\n");
				printf("0\n");
			}
		}
		//	不是0了, 而且整数部分和小数部分都有值
		else if ('0' == strInput[k][0])
		{
			//	是否是0.0000?
			int ibIsNULL = 1;
			for (int ib=0; ib < strlen(strInput[k]); ib++)
			{
				if (strInput[k][ib] != '0' && strInput[k][ib] != '.')
				{
					ibIsNULL = 0;
					break;
				}
			}
			if (0 == ibIsNULL)
			{
				//	不全是0
				if (0 == n[k])
				{
					printf("1\n");
				}
				else if (1 == n[k])
				{
					BM* bm1 = BM_init(strInput[k]);
					BM_print(bm1);
					BM_free(bm1);
				}
				else
				{
					BM* bm1 = BM_init(strInput[k]);
					BM* bm2 = BM_init(strInput[k]);

					BM* bmResult = bm1;
					for (int i=0; i < n[k] - 1; i++)
					{
						BM* temp = bmResult;
						bmResult = BM_Mul(bmResult, bm2);
						BM_free(temp);
					}

					BM_print(bmResult);
					BM_free(bmResult);
					BM_free(bm2);
				}
			}
			else
			{
				//printf("0.0\n");
				printf("0\n");
			}
		}
		else if (0 == n[k])
		{
			//	0次方, 等于1
			printf("1\n");
		}
		else if (1 == n[k])
		{
			//	1次方, 打印出原来的数即可
			BM* bm1 = BM_init(strInput[k]);
			BM_print(bm1);
			BM_free(bm1);
		}
		else
		{
			BM* bm1 = BM_init(strInput[k]);
			BM* bm2 = BM_init(strInput[k]);
			
			BM* bmResult = bm1;
			for (int i=0; i < n[k] - 1; i++)
			{
				BM* temp = bmResult;
				bmResult = BM_Mul(bmResult, bm2);
				BM_free(temp);
			}
		
			BM_print(bmResult);
			BM_free(bmResult);
			BM_free(bm2);
		}
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator