https://www.acmicpc.net/problem/30617

 

 

#include <iostream>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T;
    cin >> T;

    int l_prev = 0, r_prev = 0;
    int l, r;
    int fun_score = 0;

    for (int i = 0; i < T; i++) {

        cin >> l >> r;

        if (i > 0) {
            // 재미도 계산
            if (l != 0 && l == l_prev) {
                fun_score++;
            }
            if (r != 0 && r == r_prev) {
                fun_score++;
            }

        }
        if (r != 0 && l == r) {
            fun_score++;
        }

        // 현재 상태를 이전 상태로 업데이트
        l_prev = l;
        r_prev = r;
    }

    cout << fun_score << endl;
    return 0;
}

 

https://www.acmicpc.net/problem/16464

 

 

 

 

#문제 간단 정리

수학 문제이다

 

#문제 해결 방법

일단 n (n+1) 로 나눠지면 n-1 n n+1 로 해결이 가능한데

 

불가능한 경우는 2의 거듭제곱으로 구성되는 경우밖에 없다

2의 거듭제곱은 완벽한 대칭이기때문에 n n+1 로 분할 할 수 가없다

 

즉 2의 거듭제곱인지만 확인해주면 된다

 

 

#전체 코드

#include <iostream>
using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        long long N;
        cin >> N;
        bool canWin = false;
        while (N != 1) {
            if (N % 2 == 1) {
                canWin = true;
                break;
            }
            N /= 2;
        }
        if (canWin) {
            cout << "Gazua" << endl;
        } else {
            cout << "GoHanGang" << endl;
        }
    }
    return 0;
}

 

'[백준] > C++' 카테고리의 다른 글

백준 16692번 Greedy Scheduler [C++]  (0) 2024.08.27
백준 30617번 Knob [C++]  (0) 2024.08.26
백준 18243번 Small World Network [C++]  (0) 2024.08.26
백준 19554번 Guess the number [C++]  (0) 2024.08.25
백준 17610번 양팔저울 [C++]  (0) 2024.08.25

https://www.acmicpc.net/problem/18243

 

 

 

#문제 간단 정리

플로이드 워셜을 사용하자

 

#문제 해결 방법

 

모든 간선에서에 간선까지의 거리를 찾아야되니까 플로이드 워셜을 사용하자

 

그런데 n 이 작으므로 n^2 이상을 사용하는 bfs 를 사용해도 된다.

 

플로이드 워셜 코드

https://dfdfg42.tistory.com/entry/%ED%94%8C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%9B%8C%EC%85%9C-C%EC%BD%94%EB%93%9C

 

플로이드 워셜 C++코드

#include #include #include // std::min 사용using namespace std; // std 네임스페이스를 전역적으로 사용const int INF = 1e9; // 무한대를 의미하는 큰 값void floydWarshall(vector>& dist, int V) { // 모든 정점 쌍 (i, j)에 대해 i

dfdfg42.tistory.com

 

 

#전체 코드

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

using namespace std;

const int INF = 1e9;

void floydWarshall(vector<vector<int>>& dist, int N) {
    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (dist[i][k] < INF && dist[k][j] < INF) {
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
    }
}

int main() {
    int N, K;
    cin >> N >> K;

    vector<vector<int>> dist(N, vector<int>(N, INF));

    // 자기 자신으로의 거리는 0으로 초기화
    for (int i = 0; i < N; i++) {
        dist[i][i] = 0;
    }

    for (int i = 0; i < K; i++) {
        int A, B;
        cin >> A >> B;
        A--; // 0-based index
        B--; // 0-based index
        dist[A][B] = 1;
        dist[B][A] = 1;
    }

    floydWarshall(dist, N);

    bool flag = true;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (dist[i][j] > 6) {
                flag = false;
                break;
            }
        }
        if (!flag) break;
    }

    if (flag) {
        cout << "Small World!" << '\n';
    }
    else {
        cout << "Big World!" << '\n';
    }

    return 0;
}

https://www.acmicpc.net/problem/19554

 

 

#include <iostream>
using namespace std;

int main() {
    long long N;
    cin >> N;

    long long left = 1, right = N;

    while (left <= right) {
        long long mid = left + (right - left) / 2;
        cout << "? " << mid << endl;

        int response;
        cin >> response;

        if (response == 0) {
            cout << "= " << mid << endl;
            break;
        }
        else if (response == -1) {
            left = mid + 1;
        }
        else if (response == 1) {
            right = mid - 1;
        }
    }

    return 0;
}

https://www.acmicpc.net/problem/17610

 

 

#문제 간단 정리

 

#문제 해결 방법

 

생각보다 무게를 만들수 있는 가짓수가 많지 않기때문에

 

우선 그릇 하나만 써서 만들수 있는 무게를 모두 만든다.

 

그 이후에 만든 무게중에 두개를 빼서 만들수 있는 무게를 확인한다.

이 모든 만든 무게들을 출력해주면 된다.

 

나는 무게 만드는데는 dfs를 사용했다.

 

#전체 코드

#include <iostream>
#include <vector>
#include <cmath>


using namespace std;

vector<int> mess;
vector<int> makes;
vector<bool> check;
vector<bool> dfsCheck;
vector<int> messNext;

//한곳에 만들수 있는 모든 무게추 구하기
void dfs(int index,int sumMess) {

    for (int i = 0; i < mess.size(); i++) {
        if (dfsCheck[i] == false) {
            dfsCheck[i] = true;
            if (check[sumMess + mess[i]] == false) {
                check[sumMess + mess[i]] = true;
                messNext.push_back(sumMess + mess[i]);
                dfs(i,sumMess + mess[i]);
            }
            dfsCheck[i] = false;
        }
    }

}


int main()
{
    int k;
    cin >> k;
    int s = 0;
    mess.resize(k);
    check.resize(3000'001, false);
    dfsCheck.resize(3000'001, false);

    for (int i = 0; i < k; i++) {
        cin >> mess[i];
        s += mess[i];
        //cout << "s: " << s << '\n';
        messNext.push_back(mess[i]);
        check[mess[i]] = true;
    }

    for (int i = 0; i<mess.size(); i++) {
        dfsCheck[i] = true;
        dfs(i, mess[i]);

    }

    //두개 골라서 빼기
    for (int i = 0; i < messNext.size()-1; i++) {
        for (int j = i + 1; j < messNext.size(); j++) {
            if (check[abs(messNext[i] - messNext[j])] == false) {
                check[abs(messNext[i] - messNext[j])] = true;
            }
        }

    }

    ////무게확인
    //for (int i = 0; i <= s; i++) {
    //    if (check[i] == true) {
    //        cout << i << " ";
    //    }
    //}

    //안 만들어진 무게추 확인
    int count = 0;
    //cout << "count: ";
    for (int i = 1; i <= s; i++) {
        if (check[i] == false) {
            count++;
        }
    }
    cout << count << '\n';

}

 

https://www.acmicpc.net/problem/20209

 

 

 

 

 

#문제 간단 정리

브루트포스 완전탐색을 활용하자

bfs 를 활용하면 된다

 

 

#문제 해결 방법

 

일단 문제가 좀 설명이 길기 때문에 이해하기 좀 걸릴 수가 있다.

 

우선 이 문제에서 주목해야 될 포인트는 4가 넘어가면 5로 나눈 값으로 큐브값을 유지한다는것이다.

 

그렇다면 우리는 스위치의 개수도 8개로 가짓수가 적고

계속해서 5로 나눈다면 같은 상태가 반복된다는 걸 알 수 있다.

이부분에서 전체 가짓수가 적다는걸 파악한다

 

여기서 같은 스위치를 대략 최대 4번정도 누른다면 원래 상태로 되돌아 올 수 있다는 걸 관찰 할 수 있고

각 스위치 하나마다 최대 5가지의 상태가 파생되니까

5^k 가 총 가짓수인걸 파악할 수 있다.

 

그렇다면 중복상태를 뛰어넘어서 완전탐색을 하면 되겟다는 생각이 든다. (가짓수가 적으니까)

 

-> 여기서 중복 제거를 위해서 맵이나 셋으로 중복 상태를 관리하고

-> 완전탐색은 최소 거리를 찾아야되기 때문에 bfs 가 적절하다는 생각이 든다.

 

 

 

그렇다면 이제 구현할 차례,

유의할점은 애초에 주어진 상태가 전부 같은 숫자로 주어진 

정답 상태로 초기에 주어질 수 있음만 유의하도록 하자.

 

자세한 구현은 코드보고 이해하도록 하자

 

 

#전체 코드

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>

using namespace std;

// 모든 큐브의 숫자가 동일한지 확인하는 함수
bool equal(vector<int>& vec) {
    for (int i = 1; i < vec.size(); i++) {
        if (vec[i] != vec[0]) {
            return false;
        }
    }
    return true;
}

int main() {
    
    int n, k;
    cin >> n >> k;
    
    vector<int> cubes;
    for (int i = 0; i < n; i++) {
        int input;
        cin >> input;
        cubes.push_back(input);
    }
    
    vector<vector<int>> switches(k);
    for (int i = 0; i < k; i++) {
        int input;
        cin >> input;

        for (int j = 0; j < input; j++) {
            int input2; cin >> input2;
            switches[i].push_back(input2-1);
        }

    }

    set<vector<int>> cubeSet;


    //큐브상태,횟수
    queue<pair<vector<int>,int>> q;
    q.push({ cubes,0 });
    cubeSet.insert(cubes);

    while (!q.empty()) {

        vector<int> front = q.front().first;
        int seq = q.front().second;
        q.pop();
        if (equal(front)) {
            cout << seq  << '\n';
            return 0;
        }
         
        for (int i = 0; i < k; i++) {
            vector<int> next = front;
            for (auto a : switches[i]) {
                next[a] += i+1;
                if (next[a] > 4) {
                    next[a] %= 5;
                }
            }
            if (cubeSet.find(next) == cubeSet.end()) {
                cubeSet.insert(next);
                q.push({ next,seq + 1 });
            }

        }

    }

    cout << -1 << '\n';
    

    return 0;
}

 

 

//주석달린 버전

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>

using namespace std;

// 모든 큐브의 숫자가 동일한지 확인하는 함수
bool equal(vector<int>& vec) {
    for (int i = 1; i < vec.size(); i++) {
        if (vec[i] != vec[0]) {
            return false;
        }
    }
    return true;
}

int main() {
    int n, k;
    cin >> n >> k;
    
    vector<int> cubes(n);
    for (int i = 0; i < n; i++) {
        cin >> cubes[i];
    }
    
    vector<vector<int>> switches(k);
    for (int i = 0; i < k; i++) {
        int m;
        cin >> m;
        switches[i].resize(m);
        for (int j = 0; j < m; j++) {
            cin >> switches[i][j];
            switches[i][j]--; // 1-based index를 0-based index로 변환
        }
    }

    // 중복 상태 관리를 위한 set
    set<vector<int>> visited;

    // 큐브 상태와 스위치를 누른 횟수를 저장할 큐
    queue<pair<vector<int>, int>> q;
    q.push({cubes, 0});
    visited.insert(cubes);

    while (!q.empty()) {
        vector<int> current = q.front().first;
        int moves = q.front().second;
        q.pop();

        // 모든 큐브의 숫자가 동일하면 정답 출력 후 종료
        if (equal(current)) {
            cout << moves << endl;
            return 0;
        }

        // 각 스위치를 한번씩 눌러보는 과정
        for (int i = 0; i < k; i++) {
            vector<int> next = current;
            for (int idx : switches[i]) {
                next[idx] = (next[idx] + (i + 1)) % 5; // 스위치에 따라 숫자 변경
            }

            // 이미 방문한 상태가 아니면 큐와 set에 추가
            if (visited.find(next) == visited.end()) {
                visited.insert(next);
                q.push({next, moves + 1});
            }
        }
    }

    // 모든 경우를 탐색했음에도 정답을 찾지 못한 경우
    cout << -1 << endl;
    return 0;
}

'[백준] > C++' 카테고리의 다른 글

백준 19554번 Guess the number [C++]  (0) 2024.08.25
백준 17610번 양팔저울 [C++]  (0) 2024.08.25
백준 14760번 Reverse Nonogram [C++]  (0) 2024.08.23
백준 6123번 O Those Fads [C++]  (0) 2024.07.27
백준 1059번 좋은 구간 [C++]  (0) 2024.07.25

https://www.acmicpc.net/problem/14760

 

 

#문제 간단 정리

 

#문제 해결 방법

 

간단한 문자열 파싱 구현문제

 

주요 요구하는 구현 조건은 연속된 X 를 판별하는데 있다.

나는 연속된 x를 추적하는 seq 변수를 만들어서

 '.' 이 나온다면 초기화를 시켯다

 

여기서 seq 을 결과값 nums 이중벡터에 담는데

0이라면 담기지 않게 해두었다

그리고 나중에 비어있는 벡터에는 0을 출력하게 했다

 

#전체 코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    

    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;

        vector<vector<char>> nng(n);

        for (int i = 0; i < n; i++) {
            string s; cin >> s;
            for (int j = 0; j < n; j++) {    
                 nng[i].push_back( s[j]);
            }
        }

        vector<vector<int>> nums(2*n);

        //열 탐색
        for (int i = 0; i < n; i++) {
            int seq = 0;
            for (int j = 0; j < n; j++) {
                if (nng[i][j] == 'X') seq++;
                else {
                    if (seq != 0) {
                        nums[i].push_back(seq);
                        seq = 0;
                    }
                }
            }
            if (seq != 0) {
                nums[i].push_back(seq);
            }
        }

        //행탐색
        for (int i = 0; i < n; i++) {
            int seq = 0;
            for (int j = 0; j < n; j++) {
                if (nng[j][i] == 'X') seq++;
                else {
                    if (seq != 0) {
                        nums[n+i].push_back(seq);
                        seq = 0;
                    }
                }
            }
            if (seq != 0) {
                nums[n+i].push_back(seq);
            }
        }

        // 출력: 행 결과 먼저
        for (int i = 0; i < n; i++) {
            if (nums[i].empty()) cout << "0";
            else {
                for (auto a : nums[i]) {
                    cout << a << ' ';
                }
            }
            cout << '\n';
        }

        // 출력: 열 결과 나중에
        for (int i = 0; i < n; i++) {
            if (nums[n + i].empty()) cout << "0";
            else {
                for (auto a : nums[n + i]) {
                    cout << a << ' ';
                }
            }
            cout << '\n';
        }

    }
   
    

    return 0;
}

https://www.acmicpc.net/problem/6123

 

 

 

 

 

#문제 간단 정리

문제 그대로 구현하기

 

#문제 해결 방법

유행점수 L 이 주어지고 이거보다 저항 R 이 낮은 소들은

유행에 참여하게 되고 유행점수를 K만큼 늘리게 된다

소들이 어느정도 유행에 참여한는지를 출력하는 문제다

 

#전체 코드

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <climits>
using namespace std;

int main() {
    
    int N, L, K;
    cin >> N >> L >> K;

    vector<int> r(N);
    for(int i=0; i<N; i++){
        cin >> r[i];
    }


    bool flag = true;
    int cows = 0;
    while (flag == true) {
        flag = false;
        for (int i = 0; i < r.size(); i++) {
            if (L >= r[i]) {
                L += K;
                cows++;
                r.erase(r.begin() + i);
                flag = true;
            }
        }
    }

    cout << cows << '\n';
}

https://www.acmicpc.net/problem/1059

 

 

#문제 간단 정리

수학문제

 

#문제 해결 방법

 

대략 n보다 작은 수의 개수 * n을 포함한 n보다 큰 원소들  + n보다 큰 원소들

 

구간 만드는 규칙을 잘 살피면 되는데

n보다 작은 원소들을 n을 포함한 원소들과 짝을 만들고

n은 n보다 큰 원소들과 짝을 지어준다고 생각하자

 

#전체 코드

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <climits>
using namespace std;

int main() {
    
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    nums.push_back(0);
    sort(nums.begin(), nums.end());


    int a; cin >> a;

    int down, up;
    bool upflag = false;
    for (int k : nums) {
        if (k < a) {
            down = k;
        }
        if (upflag == false && k > a) {
            up = k;
            upflag = true;
        }
        if (k == a) {
            cout << 0 << '\n';
            return 0;
        }
    }
    //cout << "down :" << down << '\n';
    //cout << "up : " << up << '\n';
    
    int c1 = 0;
    int c2 = 0;
    for (int i = down+1; i <= a-1; i++) {
        c1++;
    }
    for (int i = a; i <= up-1; i++) {
        c2++;
    }

    cout << c1 * c2 + (c2 - 1) << '\n';
}

'[백준] > C++' 카테고리의 다른 글

백준 14760번 Reverse Nonogram [C++]  (0) 2024.08.23
백준 6123번 O Those Fads [C++]  (0) 2024.07.27
백준 1522번 문자열 교환 [C++]  (6) 2024.07.24
백준 12904번 A와 B [C++]  (1) 2024.07.23
백준 31962번 밤양갱 [C++]  (3) 2024.07.23

https://www.acmicpc.net/problem/1522

 

 

#문제 간단 정리

슬라이딩 윈도우/ 투포인터

 

#문제 해결 방법

 

중요한건 a의 개수만큼 윈도우를 만들어서

윈도우 안에 담긴 b 만큼 교체를 해주는 숫자가 최소가 되는 때를 찾는 것이다.

 

a의 개수만큼의 윈도우를 찾는다는 발상이 조금 어려울 수도 있을 것 같다.

 

#전체 코드

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <climits>
using namespace std;

int main() {
    
    string s;
    cin >> s;

    int n = s.length();
    int aCount = 0;
    int bCount = 0;
    int minBCount = INT_MAX;
    for (char c : s) {
        if (c == 'a') {
            aCount++;
        }
    }
    
    s += s;

    for (int i = 0; i < n; i++) {
        int j =i + aCount-1;

        for (int k = i; k <= j; k++) {
            if (s[k] == 'b') {
                bCount++;
            }
        }
        minBCount = min(bCount, minBCount);
        bCount = 0;
    }

    cout << minBCount << '\n';


}

'[백준] > C++' 카테고리의 다른 글

백준 6123번 O Those Fads [C++]  (0) 2024.07.27
백준 1059번 좋은 구간 [C++]  (0) 2024.07.25
백준 12904번 A와 B [C++]  (1) 2024.07.23
백준 31962번 밤양갱 [C++]  (3) 2024.07.23
백준 8972번 미친 아두이노 [C++]  (0) 2024.07.18

+ Recent posts