大數(shù)問題。C語(yǔ)言中沒有大整數(shù)類型,當(dāng)一個(gè)數(shù)超過long long時(shí)我們就沒辦法直接表示,只能通過數(shù)組模擬(字符數(shù)組,或者整形數(shù)組),與Java相比,這一點(diǎn)真是夠折磨人的,記得今年省賽的時(shí)候,有一題是關(guān)于大數(shù)的,有人直接用Java中的BigInteger類,很輕松的就搞定了,C語(yǔ)言真是無法望其項(xiàng)背。這里我們用C解一道大數(shù)乘法題,
其實(shí)模擬大數(shù)運(yùn)算就是在模擬小學(xué)生算算術(shù),這一題只牽涉到了加法和乘法,我就說著兩種操作。
加法Add():1.對(duì)位,將權(quán)值相同的各位對(duì)其
2.相加,將相應(yīng)的每一位相加
3.進(jìn)位,從低位到高位依次進(jìn)位
乘法:a*b乘法是在加法的基礎(chǔ)上完成的,跟我們手算乘法的過程一樣,依次將b的每一位與a相乘,加到一起就行了。需要注意的是b中的每一位權(quán)值是不一樣的。
為了對(duì)位方便,我們通常是將數(shù)字倒置過來,即低位在左邊,高位在右邊。字符串處理都是些細(xì)節(jié),不小心就會(huì)犯錯(cuò)誤。
以下是poj3167的代碼:
題意:給兩個(gè)數(shù)K、M,求n,使得M^n的第K為是數(shù)字7。


#include<stdio.h>
#include<stdlib.h>//zoj3167
#define LEN 310
void Add(int *A, int *B)//A[]=A[]+B[]
{
int i, j;
for(i = 0; i < LEN; i++)
{
A[i] += B[i];
}
int t = 0;
for(i = 0; i < LEN; i++)
{
int t1 = (A[i] + t) / 10;
A[i] = (A[i] + t) % 10;
t = t1;
}
}
void MultiOne(int *B, int i, int w)//B[]*(i*10^(w-1))
{
int j, k;
for(j = LEN - 1; j >= w - 1; j--)
B[j] = B[j - w + 1];
for(k = 0; k < w - 1; k++)
B[k] = 0;
for(j = 0; j < LEN; j++)
B[j] *= i;
int t = 0;
for(i = 0; i < LEN; i++)
{
int t1 = (B[i] + t) / 10;
B[i] = (B[i] + t) % 10;
t = t1;
}
}
void Set0(int *A)
{
for(int i = 0; i < LEN; i++)
A[i] = 0;
}
void Copy(int *F, int *T)
{
int i;
for(i = 0; i < LEN; i++)
T[i] = F[i];
}
int main()
{
int i, j;
int K, M;
int A[LEN];//存儲(chǔ)M^t,這是當(dāng)前乘方計(jì)算的結(jié)果
int B[LEN];//B[]和C[]一起完成對(duì)M^(t+1)的計(jì)算,B[]存儲(chǔ)M^t與b的某一位i相乘的結(jié)果,
int C[LEN];//C[]用來存儲(chǔ)計(jì)算到b的當(dāng)前位時(shí)的累加結(jié)果
while(scanf("%d%d", &K, &M) != EOF)
{
int n = 1;
Set0(A);
Set0(B);
Set0(C);
int t = M;
for(i = 0; t > 0; i++)//init A as M^1
{
A[i] = t % 10;
t /= 10;
}
while(A[K - 1] != 7)
{
Set0(C);
int t = M;
int w = 1;
while(t > 0)
{
Copy(A, B);
int ii = t % 10;
MultiOne(B, ii, w);
Add(C, B);//每一次算完B[],累加到C[]上
w++;
t /= 10;
}
Copy(C, A);
n++;
}
printf("%d\n", n);
}
//system("pause");
}
posted on 2012-08-04 09:31
小鼠標(biāo) 閱讀(1173)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
大數(shù)