大數運算

大數之間的運算在ACM競賽中一直比較熱門,其實就是模擬手算過程。在各大oj上一般是給新手用來鍛鍊使用,不過縱觀很多oj這樣的題目成功率還是相當的低。

午飯後休息沒事兒幹,隨便敲了一下大數間的乘法,這在大數運算中屬於比較簡單的一種算子。

http://cs.scu.edu.cn/soj/1003

兩個數乘積的位數 len,與兩數位數len1,len2的關係,一般len<=len1+len2,這樣的話思路就比較清晰啦,剩下的就是一些末枝問題。

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max = 500;
char front[Max];
char back[Max];
int rslt[2*Max+3];
int index_num;

 

/*功能:實現對全局數組、變量的初始化*/

void Init()
{
 memset(front,'0',sizeof(front));
 memset(back,'0',sizeof(back));
 for(int i=0;i<2*Max+3;i++)
    rslt[i] = 0;
 index_num = 0;
}

/*功能:對輸入數組的逆序。

習慣性表達:高位在前、地位在後,但輸入時恰恰相反,所以需要逆序。

但逆序不是必須的,也可以從後向前運算噻*/
void Reverse(char* cav,int len)
{
 int pnd = len/2;
 for(int i=0;i<pnd;i++)
  swap(cav[i],cav[len-1-i]);
}

/*功能:運算的具體過程模擬*/
void Multi()
{
 int len_f = strlen(front);
 int len_b = strlen(back);
 Reverse(front,len_f);
 Reverse(back,len_b);

 for(int Ick=0;Ick<len_f;Ick++)
  for(int Pnd=0;Pnd<len_b;Pnd++)
  {
   int temp = (front[Ick]-'0')*(back[Pnd]-'0');
   rslt[Ick+Pnd] += temp%10;
   rslt[Ick+Pnd+1] += temp/10;
   index_num = Ick+Pnd+1;
  }
 for(int i=0;i<=index_num;i++)
 {
  if(rslt[i]>9)
  {
   int temp = rslt[i];
   rslt[i] %= 10;
   rslt[i+1] += temp/10;
  }
 }
 index_num += 2;
}

/*輸出計算結果*/
void Print()
{
 while(!rslt[--index_num]);
 for(int i=index_num;i>=0;i--)
  printf("%d",rslt[i]);
 printf("\n");
}
int main()
{
 Init();
 while(scanf("%s%s",front,back)==2)
 {
  Multi();
  Print();
  Init();
 }
 return 0;
}
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章