hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/PS Log

22.05.15. 풀었던 문제들

1. 110 옮기기

어려워 보이는 문제였는데 해답은 간단하다.

1) 110을 제거하고, 110을 제거함으로써 생기는 모든 110도 제거한다.

2) 그렇게 남은 문자열에서 제일 뒤에 있는 0 바로 뒤에 모든 110을 넣는다.

이렇게 되는 이유는 '110'은 1보다는 앞에 와야 하고(1101보다 1110이 더 느리다) 0보다는 느리게 와야 한다(0110보다 1100이 더 느리다) 즉슨 모든 0보다 110이 뒤에 와야 한다는 말이다. 한편 110을 삽입함으로써 0의 위치는 삽입한 110의 0이 된다.

 
// 110 옮기기

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

using namespace std;

string solve(string s){
    int cnt= 0;
    for(int i = 0; i<s.length()-2; i++){
        if(s.length() < 3) break;
        if(s.length() >= i+3){
            string temp = s.substr(i, 3);
            if(temp == "110"){
                cnt++;
                s.replace(i, 3, "");
                i = max(-1, i-3);
            }
        }
    }
    int zero_idx = -1;
    for(zero_idx = s.length()-1; zero_idx >= 0; zero_idx--){
        if(s[zero_idx] == '0') break;
    }
    string target = "";
    while(cnt--) target += "110";
    s.insert(zero_idx+1, target);
    
    return s;
}

vector<string> solution(vector<string> s) {
    vector<string> answer;
    for(string& each_s : s){
        answer.push_back(solve(each_s));
    }
    return answer;
}

 

 

2. 풍선 터트리기

조건이 1백만이다. nlogn도 안되니까 DP이거나 규칙을 찾아야 한다고 생각했다. 이것도 머리 터지는 줄 알았는데.. 알고 보니 쉬운 조건이 있었다.

"어떤 풍선 기준, 양 옆(바로 옆이 아니라 끝까지)을 봤을 때 해당 풍선보다 작은 수가 양 옆에 있다면 해당 풍선은 남길 수 없다"이다.

이를 조금 설명해 보자면, 특이 규칙(단 1번만은 작은 풍선을 터트릴 수 있다)가 아니라면 i번째 풍선을 봤을 때 0~i-1의 풍선과 i+1~size-1번째 풍선 모두 i보다 값이 커야 한다. 그래야만 더 큰 값들을 사라지게 하면서 i번째 풍선이 남기 때문. 그러나 특이규칙 때문에 한 그룹의 풍선은 i보다 작아도 된다.(커도 되고, 작아도 된다는 말) 그러나 양쪽 그룹의 풍선 중 최솟값이 모두 i보다 작다면 안된다.

예를 들어보자. 편의상 0~i-1번째의 풍선을 L그룹, i+1~size-1번째 풍선을 R그룹이라 두겠다.

1) L그룹, R그룹 모두 i보다 값이 클 경우 -> 큰 값을 사라지게 하면서 i는 항상 남을 수 있다

2) L그룹의 최솟값 l, R그룹의 최솟값 r이 보드 i보다 작은 경우 -> i는 항상 남을 수 없다. 특이규칙을 사용하지 않을 경우 l과 r은 항상 남게 되는데, 그렇게 되면 l < i, r < i이므로 특이규칙을 쓰더라도 i는 항상 골라질 수 없다.

만약 특이규칙을 사용해서 한쪽 그룹에서 다른 값을 찾았다고 하자. 편의상 R그룹에서 특이규칙을 사용해서 다른 값 r'이 도출되었다고 하자. 그러면 l, i, r'을 비교하는데 만약 l과 i를 비교한다면 l<i이므로 항상 l이 골라져야 하므로 i는 남지 못한다. i과 r'을 비교한다면 i가 더 큰 경우, i는 사라지고, i가 더 작은 경우 i가 남지만 여전히 l<i이므로 i는 사라진다.

3) l < i < r 또는 r < i < l인 경우 -> 특이규칙을 사용하지 않고 L그룹에서 l, R그룹에서 r을 뽑을 수 있다. 그러면 여기서 l < i < r이면 r을 없애고 특이규칙을 사용해 l을 없애면 된다. 반대도 마찬가지.

​

정리하면, i번째 풍선을 봤을 때 L그룹의 최솟값, R그룹의 최솟값을 알아내야 한다는 게 이 문제의 요점이다.

// 풍선 터트리기

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

using namespace std;
int MAX = 1000000001;

int solution(vector<int> a) {
    int size = a.size();
    vector<int> l(size), r(size); 
    
    l[0] = MAX; // l[i] : i 왼쪽에 있는 값들의 최솟값
    for(int i = 1; i<size; i++){
        l[i] = min(a[i-1], l[i-1]);
    } 
    
    r[size-1] = MAX;  // r[i] : i 오른쪽에 있는 값들의 최솟값
    for(int i = size-2; i>=0; i--){
        r[i] = min(a[i+1], r[i+1]);
    }
    
    
    int cnt = 0;
    for(int i = 0; i<size; i++){
        //cout<<"l : "<<l[i]<<", r : "<<r[i]<<", c : "<<a[i]<<endl;
        if(l[i] < a[i] && r[i] < a[i]) continue;
        cnt++;
    }
    
    return cnt;
}

// i번째 index에 대해 왼쪽 그룹의 최솟값, 오른쪽 그룹의 최솟값을 알아내는 게 이 문제의 요점 O(n) 안에.

 

2. 입국심사

푸는 중이다. 이분탐색 내일은 진짜 정리해야징

'PS > PS Log' 카테고리의 다른 글

22.05.17. 풀었던 문제들  (0) 2022.06.23
22.05.16. 풀었던 문제들  (0) 2022.06.23
22.05.14. 풀었던 문제들  (0) 2022.06.23
22.05.13. 풀었던 문제들  (0) 2022.06.23
22.05.12. 풀었던 문제들  (0) 2022.06.23
    hyelie
    hyelie

    티스토리툴바