본문 바로가기

알고리즘 문제 풀이/C++

[C++] Bronze V - 1271. 엄청난 부자2 (Baekjoon)

 

1271. 엄청난 부자2

갑부 최백준 조교는 동전을 최소로 바꾸는데 성공했으나 김재홍 조교가 그 돈을 발견해서 최백준 조교에게 그 돈을 나누자고 따진다. 그 사실이 전 우주로 알려지자 우주에 있던 많은 생명체들이 자신들에게 돈을 분배해 달라고 당장 달려오기 시작했다. 프로토스 중앙 우주 정부의 정책인, ‘모든 지적 생명체는 동등하다’라는 규칙에 입각해서 돈을 똑같이 분배하고자 한다. 한 생명체에게 얼마씩 돈을 줄 수 있는가? 또, 생명체들에게 동일하게 분배한 후 남는 돈은 얼마인가?

http://www.acmicpc.net

문제 설명

더보기

엄청난 부자2

 

문제

갑부 최백준 조교는 동전을 최소로 바꾸는데 성공했으나 김재홍 조교가 그 돈을 발견해서 최백준 조교에게 그 돈을 나누자고 따진다.

그 사실이 전 우주로 알려지자 우주에 있던 많은 생명체들이 자신들에게 돈을 분배해 달라고 당장 달려오기 시작했다.

프로토스 중앙 우주 정부의 정책인, ‘모든 지적 생명체는 동등하다’라는 규칙에 입각해서 돈을 똑같이 분배하고자 한다.

한 생명체에게 얼마씩 돈을 줄 수 있는가?

또, 생명체들에게 동일하게 분배한 후 남는 돈은 얼마인가?

 

입력

첫째 줄에는 최백준 조교가 가진 돈 n과 돈을 받으러 온 생명체의 수 m이 주어진다. (1 ≤ m ≤ n ≤ 10^1000, m과 n은 10진수 정수)

 

출력

첫째 줄에 생명체 하나에게 돌아가는 돈의 양을 출력한다. 그리고 두 번째 줄에는 1원씩 분배할 수 없는 남는 돈을 출력한다.

 

예제 입력 1

1000 100

 

예제 출력 1

10
0

문제 해설

C++ 코드

// m의 크기가 겁내 커서 C++의 longlong으로도 해결이 안 됨...
// -> 문자열로 처리해줌!

#include <iostream>
#include <cstring>
using namespace std;

// char* = 문자열
char* big(char* a, char* b)
{
    for (int i = 0; i < strlen(a); i++)
    {
        if (a[i] < b[i]) return b; // b가 더 크면 b값 리턴
        if (a[i] > b[i]) return a; // a가 더 크면 a값 리턴
    }
    
    return a; // 값이 똑같으면 a값 리턴
}

// 나눗셈은 뺄셈을 여러번하는 연산임. -> 빼기를 계속하면 됨.
void subtract(char* a, char* b)
{
    for (int i = 0; i < strlen(b); i++) a[i] = a[i] - b[i] + '0'; // a에서 b를 뺌 (아스키코드 연산)

    for (int i = strlen(b) - 1; i >= 0; i--)
    {
        if (a[i] < '0') // 만약 아스키코드가 48('0')보다 작으면
        {
            a[i] += 10; // 10을 더하고
            a[i - 1]--; // 앞자리 수를 1 줄임
        }
    }
}

void devidesubtract(char* a, char* b, char* q, int index)
{
    q[index] = '0'; // 결과 값의 index위치에 0을 넣음

    while (a[index - 1] > '0' || big(a + index, b) == a + index)
    {
        subtract(a + index, b); // a의 index 번째에서 b를 뺌 (나머지는 a에 남음)
        ++q[index]; // q[index]를 1 더함
    }
}

void devide(char* a, char* b, char* q)
{
    int index = 0;
    int digit = strlen(a) - strlen(b); // 자리수는 아무리 커도 (a의 길이 - b의 길이)로 표현 가능함.

    while (index <= digit) devidesubtract(a, b, q, index++);

    q[index] = '\0';
}

int main()
{
    char a[1001];
    char b[1001];
    char q[1001];

    int qi = 0, ai = 0;
    cin >> a >> b;

    devide(a, b, q);

    while (q[qi] == '0') qi++; // q[qi] 번째에 0이 안 나올 때까지 qi를 증가 시킴
    while (a[ai] == '0') ai++; // a[ai] 번째에 0이 안 나올 때까지 ai를 증가 시킴

    if (q[0] == '\0') // 안 나눠지면 divide 함수에서 맨 마지막에 쓴 q[index] = '\0'만 남음 -> 몫: 0
    {
        q[0] = '0';
        q[1] = '\0';
    }

    if (a[ai] == '\0') ai--; // 만약 위에서 빼고 난 뒤에 0만 남으면, ai는 a[ai] == '\0'인 위치에서 멈추게 됨. -> ai - 1 해줘야 함.

    if (q[qi] == '\0') qi--; // 만약 q가 0만 담겨 있으면 qi는 1임. 이 상태로 출력하면 공백이 출력됨 -> qi - 1

    cout << q + qi << '\n';
    cout << a + ai << '\n';
    
    return 0;
}

 

C++ 코드 해

  1. 주석으로 대신함.