본문 바로가기
온라인 저지/BOJ

[BOJ/C] 15757 큰 수 A+B

by ahj 2021. 9. 27.

이 날의 처참한 기록... 이걸 3시간을 붙잡고 있었다. 머리가 깨질것 같다.

3시간전의 처음 2개는 뭣도 모르고 C++이 무슨 파이썬이라도 되는 줄 아는 냥 그냥 입력값을 더하는 코드를 짰던 것이고

2시간의 사투를 벌인 저 900글자를 상회하는 저 치열한 코드들은 하나만 골라서 보면 다음과 같다.

#include <stdio.h>

int main()
{
  char a[10001], b[10001], c[10001];
  int a_len, b_len;
  scanf("%s %s", a, b);
  for(int i=0;a[i]!=0;i++){a_len=i;}//a 길이 구하기
  for(int i=0;b[i]!=0;i++){b_len=i;}//b 길이 구하기
  for(int i=0;i<=a_len/2;i++){
    char temp = a[i];
    a[i] = a[a_len-i];
    a[a_len -i] = temp;
  }
  for(int i=0;i<=b_len/2;i++){
    char temp = b[i];
    b[i] = b[b_len-i];
    b[b_len -i] = temp;
  }//a, b 자리 바꾸기,
  int max = a_len>b_len?a_len:b_len;//a와 b 중에 더 긴 배열 길이를 최대로 잡아주기
  for(int i=0;i<=max;i++){
    c[i]=a[i]+b[i];//어차피 자신의 길이보다 더 긴 배열은 이후 값들이 어차피 0이기 때문에 그냥 더해줘도 상관 없다. 처음에는 이것마저 경우의 수를 나눠서 짜줬다..
  }
  for(int i=0;i<max;i++){//0
    if(106<=c[i]) {
      c[i]-=58;
      c[i+1]+=1;
    }//두 문자형을 더한 값이 106이상은 '5'+'5'의 값에 따라서 결정했다
    else if(96<=c[i]&&c[i]<106){
      c[i]-=48;
    }//두 자리수를 안넘어가면 그냥 '0'에 해당하는 48만 빼주고
    else if(c[i]>=58){c[i]-=10; c[i+1]+=1;}//'9'+1처럼 자리수 올라와서 처리되는 값은 10만 빼줘야한다.
  }
  if(c[max]>=106){
    c[max]-=58;
    c[max+1]=49;
  }
  else if(c[max]>=58){c[max]-=10; c[max+1]=49;}
  else if(96<=c[max]&&c[max]<106){c[max]-=48;}//여기까지는 마지막 제일 큰 자리수 값 처리 과정이다.
  for(int i=max+1;i>=0;i--){
    printf("%c", c[i]);//문자로 출력
  }
  
  return 0;
}

이걸 짜낸 것도 진짜.. 경우의 수 노가다를 해가면서 다소 멍청하게 코드를 짠것 같은데 하..

여기서 또 경우의 수를 빠뜨린 줄 알고 2시간을 헤맸다.

다른 질문들 찾아서 각종 반례들을 넣어봐도 다 정상적으로 출력되고.. 도대체 뭐가 문젠지 몰랐다.

하지만 눈 여겨 보지 않았던 다른 사람들 코드의 선언 부에서 충격적인 사실을 깨닫게 되었다. 출력을 문자열로 출력하면 안됐다.... 하 이것 하나 때문에 저녁 계획이 다 망가졌다

최종적으로 정답 코드는 정수열 처리를 해주니까 오히려 논리도 간단해지고 모든게 간단해졌다...

#include <stdio.h>

int alen, blen;
int main()
{
  char a[10002]={0}, b[10002]={0};
  int c[10003]={0}, cnt;
  scanf("%s %s", a, b);
  for(int i=0;a[i]!=0;i++){a[i]-='0'; alen=i;}
  for(int i=0;b[i]!=0;i++){b[i]-='0'; blen=i;}
  for(int i=0;i<=alen/2;i++){
    char temp = a[i];
    a[i] = a[alen-i];
    a[alen -i] = temp;
  }
  for(int i=0;i<=blen/2;i++){
    char temp = b[i];
    b[i] = b[blen-i];
    b[blen -i] = temp;
  }
  int max = alen>blen?alen:blen;
  for(int i=0;i<=max;i++){
    c[i]+=a[i]+b[i];
    if(c[i]>9){c[i]-=10; c[i+1]+=1; cnt=1;}
    else cnt=0;
  }
  max = (cnt==1)?max+1:max;
  for(int i=max;i>=0;i--){printf("%d", c[i]);}
  return 0;
}

class 구현 연습이나 할까 했는데 지쳐서 그냥 제출하고 맞고 쉬어야 겠다. 원래 오는 단계별 문제에서 기본 수학 1까지는 다 풀려고 했는데 풀까말까 고민 중이다... 저것도 30프로 대의 문제라서 운동하고 머리 좀 식히고 다시 생각해봐야겠다.

 

그래도 이런 문제들 덕분에 C가 가진 입력 숫자들의 한계에 대해서도 아게 되고

파이썬의 위대함도 알게 되니 감사한 일이다.

 

오늘의 교훈: 출력할 값이 문자형일지 정수형일지 잘 생각하고 짜자 큰 숫자는 파이썬 최고

댓글