PS

BOJ 27740 : 시프트 연산

lickelon 2024. 4. 15. 22:50
  • 문제 링크 : boj.kr/27740
  • 난이도 : G4
  • 태그 : 애드혹, 그리디, 브루트포스
 

27740번: 시프트 연산

$0$과 $1$로 이루어진 길이 $N$의 수열 $A_1,A_2,\cdots,A_N$이 주어진다. 주어진 수열에는 다음과 같이 정의된 두 가지 연산을 원하는 대로 적용할 수 있다. L-시프트: 수열의 원소를 한 자리씩 앞으로 옮

www.acmicpc.net


코드

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()

#define INF 0x7FFFFFFF

using namespace std;

using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll, ll>;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;
    vector<int> arr(n);
    for(auto &u : arr) cin >> u;

    int l, r;
    l = r = 0;
    int ans = INF;
    pii ansp;
    while(r < n && l < n) {
        while(r < n && arr[r] == 1) {
            r++;
        }
        l = r-1;
        while(r < n && arr[r] == 0) {
            r++;
        }
        int temp = 0;
        temp += min(n-r, l+1);
        temp += n-r + l+1;
        if(temp < ans) {
            ans = temp;
            ansp = {l+1, n-r};
        }
    }
    cout << ans << "\n";
    if(ansp.first <ansp.second) {
        for(int i = 0; i < ansp.first; i++) {
            cout << "L";
        }
        for(int i = 0; i <ansp.first + ansp.second; i++) {
            cout << "R";
        }
    }
    else {
        for(int i = 0; i < ansp.second; i++) {
            cout << "R";
        }
        for(int i = 0; i <ansp.first + ansp.second; i++) {
            cout << "L";
        }
    }
    return 0;
}

풀이

직관적으로 생각해보면 0으로만 이루어진 구간이 있을 때, 양 옆의 1들을 없애주면 되는 문제이다.

없앨 때 한 쪽을 전부 없애고, 다른 한 쪽을 없애주는 것이 효율적임을 알 수 있다.

0으로만 이루어진 구간을 브루트포스로 구해준 뒤에 양쪽 중 짧은 쪽을 먼저 없애주면 된다.

728x90

'PS' 카테고리의 다른 글

BOJ 12994 : 이동3-2  (0) 2024.04.17
BOJ 2258 : 정육점  (0) 2024.04.16
BOJ 27440 : 1로 만들기 3  (1) 2024.04.14
BOJ 22981 : 휴먼 파이프라인  (0) 2024.04.13
BOJ 18234 : 당근 훔쳐 먹기  (0) 2024.04.12