| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Problem 1001 ask for helpi 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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator