はなたの日記

ギターのコードについて書きます

Volume0-0015 National Budget

問題
国家予算 | Aizu Online Judge

多倍長整数の足し算を実装する問題です。
基本情報技術者試験の午後問題で解いたことがあり、今回はそのアルゴリズムを参考に実装しました。

参考
基本情報技術者過去問題 平成21年秋期 午後問9|基本情報技術者試験.com

簡単にまとめると
1.入力された文字列を下位から9桁ずつ分割
2.分割したものを加算
3.表示
という感じです。考え方は簡単なのですが、実装にめちゃくちゃ時間がかかりました。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 101
#define KETA 9
#define INF 1000000000
#define KMAX 12


typedef struct MegaNum{
 char str[MAX];
 long num[KMAX];
}MegaNum;


void Convert(MegaNum *X){
 int len=strlen((*X).str);
 char temp[KETA+1];
 int i,j,k;

/*先頭のあまり*/
 for(i=0;i<len%KETA;i++)temp[i]=(*X).str[i];
 temp[len%KETA]='\0';
 (*X).num[len/KETA]=atoi(temp);

 i=len/KETA-1;
 j=len%KETA;

 while(i>=0){

   for(k=0;k<KETA;k++){
     temp[k]=(*X).str[j];
     j++;
   }
   temp[KETA]='\0';
   (*X).num[i]=atoi(temp);
   i--;

 }


return;
}


int Getketa(int x){
 int cnt=0;

 if(x==0)return 1;

 while(x!=0){
  x=x/10;
  cnt++;
 }


 return cnt;

}


void Getsum(MegaNum *A,MegaNum *B,MegaNum *C){
 int a=strlen((*A).str)/KETA;
 int b=strlen((*B).str)/KETA;
 int i,j,x;
 int temp[10];

 for(i=0;i<KMAX;i++)(*C).num[i]=0;


 for(i=0;i<=b;i++){

  (*C).num[i]+=((*A).num[i]+(*B).num[i]);

  if((*C).num[i]>=INF){
    (*C).num[i+1]++;
    (*C).num[i]-=INF;
  }

 }


 for(i=b+1;i<=a;i++){

  (*C).num[i]+=(*A).num[i];

  if((*C).num[i]>=INF){
    (*C).num[i+1]++;
    (*C).num[i]-=INF;
  }

 }

 if((*C).num[a+1]==1){
   if(a+1>=9){printf("overflow\n");return;}
   printf("1");
   i=a;
 }
 else {
  if(a>=9){printf("overflow\n");return;}
  if(a==8 && (*C).num[a]>=100000000){printf("overflow\n");return;}
  printf("%ld",(*C).num[a]);
  i=a-1;
 }

 while(i>=0){

    x=KETA-Getketa((*C).num[i]);
    for(j=0;j<x;j++)printf("0");
    printf("%ld",(*C).num[i]);
    i--;
 }
 

printf("\n");


return;
}


int main(){
 MegaNum A,B,C,temp;
 int n,i;

 scanf("%d",&n);

 for(i=0;i<n;i++){

  scanf("%s",A.str);
  scanf("%s",B.str);

  if(strlen(A.str)>=81 || strlen(B.str)>=81)printf("overflow\n");
  else{

   if(strlen(A.str) < strlen(B.str)){
     temp=A;
     A=B;
     B=temp;
   }

   Convert(&A);
   Convert(&B);

   Getsum(&A,&B,&C);

  }

 }
return 0;
}

分割は割とパパッと実装できたのですが、加算の所で躓きました。
構造体はアドレスを渡さないと、中身が更新されないということを忘れていました…
汚すぎるし、計算結果をただ表示しているだけというお粗末仕様なので、いつかもっときれいに書き直してみます。