Codeforces #805 Div. 3 Upsolving
G번 빼고 했다.(아직 배우지 않은 lca)
프로그래머스 코딩테스트 실전 대비 모의고사 1회
1번
두 수에서 각 숫자의 개수를 xcnt, ycnt에 기록한 후 xcnt[i], ycnt[i] 중 작은 값 만큼 정답에 붙여넣으면 된다. 0은 special case기 때문에 따로 예외처리 해 주면 된다.
#include <string> #include <vector> using namespace std; string solution(string X, string Y) { vector<int> xcnt(10, 0), ycnt(10, 0); for(char c : X){ xcnt[c-'0']++; } for(char c : Y){ ycnt[c-'0']++; } string answer = ""; for(int i = 9; i>=0; i--){ int value = min(xcnt[i], ycnt[i]); if(i == 0 && answer == ""){ if(value >= 1) answer += to_string(0); } else{ for(int v = 0; v<value; v++){ answer += to_string(i); } } } return answer == "" ? "-1" : answer; }
2번
sliding window로 쉽게 풀 수 있는 문제. string의 비교에 O(10)만큼 걸릴 것이라 예측했기 때문에 string 비교 대신 mapper를 사용해서 만들었다. sliding window의 size는 10이다.
#include <string> #include <map> #include <vector> using namespace std; bool allsale(vector<int>&number, vector<int>&want_numbers){ for(int i = 0; i<number.size(); i++){ if(number[i] <= want_numbers[i]) continue; else return false; } return true; } int solution(vector<string> want, vector<int> number, vector<string> discount) { vector<int> want_numbers(number.size(), 0); // want_number[i] : idx에 해당하는 제품 재고 map<string, int> m; // m[str] : string에 해당하는 제품의 idx for(int i = 0; i<want.size(); i++){ m[want[i]] = i; } // two-pointer 초기값 설정 for(int i = 0; i<10; i++){ if(m.find(discount[i]) == m.end()) continue; want_numbers[m[discount[i]]]++; } int answer = 0; if(allsale(number, want_numbers)) answer++; for(int i = 10; i<discount.size(); i++){ if(m.find(discount[i-10]) != m.end()){ // 10일 전 것은 현재 장바구니에서 뺌 want_numbers[m[discount[i-10]]]--; } if(m.find(discount[i]) != m.end()){ // 추가할 것 추가 want_numbers[m[discount[i]]]++; } if(allsale(number, want_numbers)) answer++; // 조건 맞으면 ++ } return answer; }
3번
까다로웠던 simulation 문제. order의 index와 현재 컨베이어 벨트 제일 앞에 나와 있는 target 이렇게 2개의 index를 사용할 것이다.
- 만약 target(현재 제일 앞에 있는 번호)와 order[i]가 동일하다면 바로 넣을 수 있다. i++, target++을 해 준다.
- 만약 target < orders[i]라면 target보다 더 큰 것을 올려야 하므로, target이 orders[i]가 될 때 까지 stack에 target을 넣고, target++을 해 준다.
- 만약 target > orders[i]라면 target보다 더 작은 것을 올려야 하므로, sub container belt, stack을 봐야 한다. 그런데 여기서, stack이 비었거나 stack의 top이 orders[i]와 다르다면 더 이상 순서를 맞춰줄 수 없다. 바로 종료. 그렇지 않다면 stack pop하고 i++, answer++을 해 준다.
#include <string> #include <stack> #include <vector> using namespace std; int solution(vector<int> orders) { int answer = 0, n = orders.size(); int target, i; stack<int> stk; for(target = 1, i = 0; i<orders.size();){ // target : 현재 제일 앞에 있는 것 if(target == orders[i]){ // 순서가 맞으면 바로 넣음 answer++; i++; target++; } else if(target < orders[i]){ // target보다 더 큰걸 올려야 하면 sub에 넣음 while(target <= n && target < orders[i]){ stk.push(target); target++; } } else{ // target보다 더 작은 걸 올려야 하면 stack에서 빼내야 함 if (!stk.empty() && stk.top() == orders[i]) { stk.pop(); i++; answer++; } else{ // stack에서 못 뺀다면, 더 이상 순서를 맞출 수 없음 break; } } } return answer; }
4번
n by n matrix a, b가 주어졌을 때 a에서 최소의 operation으로 b를 만들 때, n을 구하는 문제. 각 operation은 row를 모두 뒤집거나 col을 모두 뒤집거나 이다.
그래서 나는 a - b를 diff라는 matrix로 정의하고 [어차피 row-col로 하나 col-row로 하나 결과는 동일하니까] row부터 모두 처리하고, col을 다음으로 처리했다. 그런데 무슨 반례가 있나 보다. 75점 나온다. 근데 무슨 반롄지 모르겠다......
#include <string> #include <vector> #include <iostream> using namespace std; int n; // vector v의 값을 reverse해서 vector return vector<int> rev(vector<int> v){ for(int &i : v){ i = 1 - i; } return v; } // vector a, vector b의 elem이 모두 같으면 true, 다르면 false bool cmp(vector<int> &a, vector<int>& b){ for(int i = 0; i<a.size(); i++){ if(a[i] != b[i]) return false; } return true; } int solve(vector<vector<int>> diff, vector<int>&standard, vector<int>& rev_standard){ int answer = 0; for(int r = 1;r<n; r++){ if(cmp(standard, diff[r])) continue; // stan과 같으면 pass else if(cmp(rev_standard, diff[r])){ // stan과 다른 경우 - rev_stan과 같으면 뒤집고 ans++ diff[r] = rev(diff[r]); answer++; } else return -1; // stan과도 다르고 rev_stan과도 다르면 만들 수 없다. } for(int i : standard) if(i == 1) answer++; // 모든 행이 stan과 같아졌음. stan에 있는 1 숫자만큼 ans++ return answer; } int solution(vector<vector<int>> beginning, vector<vector<int>> target) { n = beginning.size(); vector<vector<int>> diff(n, vector<int>(n, 0)); for(int r= 0; r<n; r++){ for(int c= 0 ; c<n; c++){ if(beginning[r][c] != target[r][c]){ diff[r][c] = 1; // 다르면 1, 같으면 0 } } } vector<int> standard(diff[0].begin(), diff[0].end()); // 기준 행 vector<int> rev_standard = rev(standard); // 기준 행 뒤집은 것 int a = solve(diff, standard, rev_standard); int b = solve(diff, rev_standard, standard) + 1; //cout<<a<<' '<<b<<endl; return min(a, b); }
백준 단계별 25 그래프와 순회
7576 토마토
7569 토마토
16929 뱀과 사다리 게임
2206 벽 부수고 이동하기
벽을 부순 상태, 벽을 부수지 않은 상태 2가지 상태에 대한 state가 필요하기 때문에 dist를 3차원 배열로 선언한다.
그러면 BFS 할 때, 조건은 다음과 같이 된다. 이런 state에 따른 BFS/DFS 문제는 프로그래머스에서 풀었었다.
dist[r][c][0]은 벽을 부수지 않은 상태에서 [0, 0]에서 [r, c]까지 최단거리
dist[r][c][1]은 벽을 부순 상태에서 [0, 0]에서 [r, c]까지 이동한 최단거리
로 두고 풀면 쉽게 풀릴 것이다.
- 지금까지 벽을 부순 경우
- 다음 칸이 무조건 벽이 없어야 함
- 지금까지 벽을 부수지 않은 경우
- 다음 칸이 벽인 경우 해당 칸으로 넘어가고, didBroke를 true로 바꿈, BFS 계속 함
- 다음 칸이 벽이 아닌 경우 그대로 넘어 감
int dr[4] = {1, 0, -1, 0}; int dc[4] = {0, 1, 0, -1}; void solve(){ int INF = 100000000; int N, M; cin>>N>>M; vector<string> grid(N); vector<vector<vector<int>>> dist(N, vector<vector<int>>(M, vector<int>(2, INF))); dist[0][0][0] = dist[0][0][1] = 1; // dist[r][c][0] : dist from [0, 0] to [r, c], 벽 부수지 않음 // dist[r][c][1] : dist from [0, 0] to [r, c], 벽 부숨 for(string &str : grid) cin>>str; queue<pair<pii, bool>> q; q.push({{0, 0}, false}); // .first : 좌표. second :부순 여부 while(!q.empty()){ pii cur = q.front().first; bool didBroke = q.front().second; int cr = cur.first; int cc = cur.second; q.pop(); for(int d = 0; d<4; d++){ int nr = cr + dr[d]; int nc = cc + dc[d]; if(0 <= nr && nr < N && 0 <= nc && nc < M){ if(grid[nr][nc] == '0' && dist[nr][nc][didBroke] == INF){ q.push({{nr, nc}, didBroke}); // 안부수고 진행 dist[nr][nc][didBroke] = dist[cr][cc][didBroke] + 1; } if(!didBroke && grid[nr][nc] == '1' && dist[nr][nc][1] == INF){ q.push({{nr, nc}, true}); // 안부셨다면 부실 수 있음 dist[nr][nc][1] = dist[cr][cc][didBroke] + 1; } } } } int answer = min(dist[N-1][M-1][0], dist[N-1][M-1][1]); answer = (answer == INF ? -1 : answer); cout<<answer; }
1707 이분 그래프
'PS > PS Log' 카테고리의 다른 글
22.08.15. 풀었던 문제들 *** vector erase, remove (0) | 2022.08.15 |
---|---|
22.08.14. 풀었던 문제들 (0) | 2022.08.15 |
22.08.12. 풀었던 문제들 - Codeforces #805 Div. 3 4/7 (0) | 2022.08.13 |
22.08.11. 풀었던 문제들 (0) | 2022.08.13 |
22.08.10. 풀었던 문제들 (0) | 2022.08.10 |