4 분 소요

실습 21

실습 22

문제 설명

첫 번째 분수의 분자와 분모를 뜻하는 denum1, num1, 두 번째 분수의 분자와 분모를 뜻하는 denum2, num2가 매개변수로 주어집니다. 두 분수를 더한 값을 기약 분수로 나타냈을 때 분자와 분모를 순서대로 담은 배열을 return 하도록 solution 함수를 완성해보세요.

제한사항

0 < denum1, num1, denum2, num2 < 1,000

입출력 예

denum1 num1 denum2 num2 result
1 2 3 4 [5, 4]
9 2 1 3 [29, 6]

내가 제출한 코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int getMul(int num1, int num2)
{
    int returnVal = 1;
    int min = num1 > num2 ? num2 : num1;
    int max = num1 > num2 ? num1 : num2;

    for (int i = 2; i <= max; i++)
    {
        if (num1 % i == 0 && num2 % i == 0)
        {
            returnVal *= i;
            num1 /= i;
            num2 /= i;
        }
    }

    returnVal *= num1;
    returnVal *= num2;

    return returnVal;
}
// 최대 공약수 구하기
int getDiv(int num1, int num2)
{
    int min = num1 > num2 ? num2 : num1;
    int returnVal = 0;
    for (int i = min; i > 0; i--)
    {
        if (num1 % i == 0 && num2 % i == 0)
        {
            returnVal = i;
            break;
        }
    }

    return returnVal;
}
vector<int> solution(int denum1, int num1, int denum2, int num2)
{
    vector<int> answer;
    int resultNum = 0;
    int resultDenum = 0;

    // 최소 공배수 구하기 -> 굳이 필요는 없음. 왜냐면 나중에 어차피 또 기약분수를 만들기 위해서 처리를 해주어야되기 때문
    resultNum = getMul(num1, num2);
    resultDenum = (denum1 * (resultNum / num1) + denum2 * (resultNum / num2));

    // 최대 공약수
    int div = getDiv(resultDenum, resultNum);
    resultDenum /= div;
    resultNum /= div;

    answer.push_back(resultDenum);
    answer.push_back(resultNum);

    for (auto i : answer)
        cout << i << endl;
    return answer;
}

교수님 코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

// denum은 ref로 전달할 것이다. = 두개 이상의 ㄱ밧을 리턴할 때는 ref로 처리하는게 더 간단하게 될 수 있다.
// 리턴 ㄱ밧이 굳이 한개라면 굳이 ref로 처리할 이유가 없다.
void getSum(int &denum, int &num, int denum1, int num1, int denum2, int num2)
{
    num = num1 * num2;
    denum = denum1 * num2 + denum2 * num1;
}

void postDiv(int &denum, int &num)
{
    int div = 0;
    int min = denum > num ? num : denum;

    // for (int i = min; i > 0; i--)
    // {
    //     if (denum % i == 0 && num % i == 0)
    //         div = i;
    // }
    // denum /= i;
    // num /= i;
    for (int i = 2; denum > 1 && num > 1 && num >= i;)
    {
        // 같은 숫자로 여러번 나누어 줄지도 모르기 때문에 또다시 동일한 i로 한 번 더 나눠 볼 수 있도록 확인하는 것이다.
        if (denum % i == 0 && num % i == 0)
        {
            denum = denum / i;
            num = num / i;
        }
        else
            i++;
    }
}
vector<int> solution(int denum1, int num1, int denum2, int num2)
{
    vector<int> answer;

    int denum, num;

    getSum(denum, num, denum1, num1, denum2, num2);
    postDiv(denum, num); // 기약 분수 만들기

    answer.push_back(denum);
    answer.push_back(num);
    return answer;
}
/*
기약분수 신경 안쓰고 그냥 일단 num1 * num2를 진행을 해 그런다음에 기약분수를 만든다 .
여기서 넘겨야되는 ㄱ밧, 받아야되는 ㄱ밧이 2개이기 때문에 ref를 활용해서 인자로 전달해주었다.
넘겨야될 값이 2개니까 call by ref로 처리ㅐㅆ다. 2개 이상의 ㄱ밧에 대한 ㄱeturn을 처리할 때 유용하게 잘 쓰인다. 그런 다음 공약수를 발견하면 그걸로 나누어 주는 수를 나누어 주고 싶은거야. 2부터 출발해서 두개 의 숫자보다 작은 숫자가 공약수로서 의미가 있다. 그래서 for문이 도는 조건이 i >= denum, num 이라는 조건이 붙은 것이다. 여기에 추가적으로 붙은 조건은 공약수를 발견하면 간은 공약수를 가지고 자꾸 나눌꺼야. 그래서 나누고 나누고 나누다가 둘 주 ㅇ 하나가 1이 되면 멈출 것이다. 그래ㅓㅅ denum > 1, num > 1을 만족시켜야 된다는 것이ㅏㄷ. */

실습 23

문제 설명

앞에서부터 읽을 때와 뒤에서부터 읽을 때 똑같은 단어를 팰린드롬(palindrome)이라고 합니다. 예를들어서 racecar, 10201은 팰린드롬 입니다.

두 자연수 n, m이 매개변수로 주어질 때, n 이상 m 이하의 자연수 중 팰린드롬인 숫자의 개수를 return 하도록 solution 함수를 완성해 주세요.

제한사항

m은 500,000이하의 자연수이며, n은 m 이하의 자연수입니다.

입출력 예

n m result
1 100 18
100 300 20

내가 제출한 코드

#include <iostream>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

bool isPalind(int num)
{
    string strNum = to_string(num);
    int len = strNum.size();

    if (len % 2 != 0)
        len--;

    for (int i = 0; i < (len / 2); i++)
    {
        if (strNum[i] != strNum[strNum.size() - i - 1])
            return false;
    }
    return true;
}
int solution(int n, int m)
{
    int answer = 0;

    for (int i = n; i <= m; i++)
    {
        if (isPalind(i))
            answer++;
    }
    cout << answer << endl;
    return answer;
}

교수님 코드

#include <iostream>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

void getStr(string &str, int k)
{
    // string은 char의 array이므로 리턴하게되면 복사가 벌어지고 스트링이 짧으면 상관 없지만 그게 길다면 그냥 리턴으로 처리하면 value의 복사가 필요하므로 복사에 요구되는 시간이 길어진다.. 그래서 call by ref로 처리하ㅡㄴ게 조금 더 빠르다.
    str = "";
    // 숫자를 string으로 만들고 두개를 뒤집어서 같은지를 비교
    for (int i = k; i > 0; i /= 10)
    {
        char temp = (k % 10) + '0';
        str = temp + str;
    }
}
void getRevStr(string &revstr, int k)
{
    revstr = "";
    // 숫자를 string으로 만들고 두개를 뒤집어서 같은지를 비교
    for (int i = k; i > 0; i /= 10)
    {
        char temp = (k % 10) + '0';
        revstr += temp;
    }
}
bool isPali(int k)
{
    string str, revstr;

    getStr(str, k);       // k를 str로 ㅂ꿀거임
    getRevStr(revstr, k); // k를 뒤집어서 revstr로 만들꺼임

    cout << str << endl;
    cout << revstr << endl;

    if (str == revstr)
        return true;
    else
        return false;
}
int solution(int n, int m)
{
    int answer = 0;

    for (int i = n; i <= m; i++)
    {
        if (isPali(i))
            answer++;
    }
    return answer;
}

댓글남기기