< 본 게시글은 유튜버 [ 동빈나 ] 님의 유튜브 영상과 git hub 교재 를 공부하고 정리한 글 입니다. >
[ Greedy ]
[#1 1이 될 때까지] / [#2 곱하기 혹은 더하기- Face book 인터뷰 기출] / [#3 모험가 길드- 핵심 유형]
---------------------------------------------------------------------------------------------------------------------------------
#1 1이 될 때까지


[ 내 풀이 ]
#include<iostream> using namespace std; int n, k; int rest; int cnt; int main() { cin >> n >> k; while (n != 1&&n>=k) { rest = n % k; cnt += rest; n = n - rest; n = n / k; cnt++; } if (n < k) { while (n != 1) { n--; cnt++; } } cout << cnt; return 0; }
[ 정답 ]
#include <bits/stdc++.h> using namespace std; int n, k; int result; int main() { // N, K를 공백을 기준으로 구분하여 입력 받기 cin >> n >> k; while (true) { // N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 int target = (n / k) * k; result += (n - target); n = target; // N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출 if (n < k) break; // K로 나누기 result += 1; n /= k; } // 마지막으로 남은 수에 대하여 1씩 빼기 result += (n - 1); cout << result << '\n'; }
int cnt = 0; cin >> N >> K; while (N != 1) { if (N%K == 0) { N /= K; cnt++; } else { N -= 1; cnt++; } } cout << cnt;
배운 점 :
int target = (n / k) * k ;
n 이 k 에 나누어 떨어지지 않더라도 나누어 떨어지는 가장 가까운 수를 찾을 수 있다.
if( n < k) break이런 나누기 문제일땐 항상 n이 k 보다 작을 경우를 생각해줘야한다. 안그러면 while 문에서 무한 루프에 빠진다.
result += (n - 1); // 마지막으로 남은 수에 대하여 1씩 빼기
while (n != 1) { n--; cnt++; }
내가 쓴 코드를 그냥 cnt += ( n-1 ) ; 한줄로 처리 할 수 있었다.
#2 곱하기 혹은 더하기


[ 내 풀이 ]
#include<iostream> #include<vector> #include<algorithm> #include<string> using std::cout; using std::cin; using std::vector; std::string S; int main() { std::ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); vector<int> input; cin >> S; for (int i = 0; i < S.length(); i++) { input.push_back(S[i] - '0'); } int result=0; for (auto itr = input.begin(); itr != input.end(); itr++) { if (result == 0) { result += *itr; } else { if (*itr == 1 || *itr == 0) { result += *itr; } else { result *= *itr; } } } cout << result; return 0; }
[ 정답 ]
#include <bits/stdc++.h> using namespace std; string str; int main(void) { cin >> str; // 첫 번째 문자를 숫자로 변경한 값을 대입 long long result = str[0] - '0'; for (int i = 1; i < str.size(); i++) { // 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 int num = str[i] - '0'; if (num <= 1 || result <= 1) { result += num; } else { result *= num; } } cout << result << '\n'; }
배운 점 :
- 그냥 두 수 중에서 하나라도 '0' 혹은 '1' 인 경우를 생각하면 되는데..
나는 지엽적으로 s[i]의 값만 가지고 0 이나 1이면 어떻게 해야지 하고 생각했다. 그래서 코드가 쓸데없이 길어졌다.
for (auto itr = input.begin(); itr != input.end(); itr++) { if (result == 0) { result += *itr; } else { if (*itr == 1 || *itr == 0) { result += *itr; } else { result *= *itr; } } }
#3 모험가 길드



[ 내 풀이 ] - 실패
#include<iostream> #include<algorithm> #include<vector> using namespace std; int answer; int n, x; vector<int> traveler; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n; traveler.reserve(n); for (int i = 0; i < n; i++) { cin >> x; traveler.push_back(x); } sort(traveler.begin(), traveler.end()); int max=0; while (max <= traveler.size()) { auto itr = traveler.begin(); max = *itr; int i = 0; for (i; i < max; i++) { if (traveler[i] > max) { max = traveler[i]; break; } } traveler.erase(itr, itr + i); } return 0; }
[ 정답 ]
#include <bits/stdc++.h> using namespace std; int n; vector<int> arr; int main(void) { cin >> n; for (int i = 0; i < n; i++) { int x; cin >> x; arr.push_back(x); } sort(arr.begin(), arr.end()); int result = 0; // 총 그룹의 수 int count = 0; // 현재 그룹에 포함된 모험가의 수 int p = 0; for (int i = 0; i < n; i++) { // 공포도를 낮은 것부터 하나씩 확인하며 p = arr[i]; // 현재 그룹의 공포도 count += 1; // 현재 그룹에 해당 모험가를 포함시키기 if (count >= p) { // 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 result += 1; // 총 그룹의 수 증가시키기 count = 0; // 현재 그룹에 포함된 모험가의 수 초기화 } } cout << result << '\n'; // 총 그룹의 수 출력 }
배운 점 :
- 문제를 너무 어렵게 접근하려고 했었다.
( 매번 이렇게 공식이 없는 문제를 풀때마다 이상한 길로 새는거 같다. )
먼저 문제 접근 방법부터 곰곰히 생각해보고 방향성이 잡혔을때 문제풀이를 시작해야겠다.
- reserve 해야되는걸 resize 해서 의도치 않게 원소 0이 traveler에 들어있었다. ( 조심하자 )
traveler.resize(n);
'PS > 이코테' 카테고리의 다른 글
[ 이코테 Chapter 4. 구현 ] - 복습 O (0) | 2021.12.24 |
---|---|
[ 이코테 3. DFS/BFS ] / 복습 ○ (0) | 2021.11.09 |