8.1주차
실습 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;
}
댓글남기기