본문 바로가기

USACO/Bronze

USACO 2024 December Contest

1. Roundabout Rounding

이 문제의 체인반올림은 1의자리에서부터 반올림을 해가면서 가장 높은자리까지 반올림을 하는 새로운 계산법이다. 이때, 체인반올림과 그냥 반올림을 한 수가 다른 1 ~ 주어진 N까지의 모든 수의 개수를 구하는 문제이다.

간단히 45…55이 수부터 가장 높은자리에서의 반올림과 체인반올림이 달라지고, 50…00부터 같아짐으로 이 사이의 수를 모두구하면된다.

만약 N이 50…00보다 크다면 50…00으로 N을 갱신후, 45…54를 빼주면 된다.

code

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
using ll = long long;

ll P[11];

int main()
{
    int t;
    scanf("%d", &t);
    P[2] = 5;
    for(int i=3;i<=10;i++) {
        P[i] = P[i - 1];
        ll res = 0;
        for(int j = 0;j<i - 1;j++) {
            res += 4 * pow(10, j);
        }
        res++;
        P[i] += pow(10, i - 1) - res;
    }
    while(t--) {
        int N;
        vector <int> vec;
        scanf("%d", &N);
        ll n = (ll)N;
        while(N >= 10) {
            vec.push_back(N % 10);
            N /= 10;
        }
        vec.push_back(N);
        reverse(vec.begin(), vec.end());
        ll ans = P[vec.size() - 1];
        ll res = 0;
        for(int i = 0;i<vec.size();i++) {
            res += (ll)(4 * pow(10, i));
        }
        if(vec[0] >= 5) {
            n = (ll)(5 * pow(10, vec.size() - 1));
            n--;
        }
        res++;
        if(res <= n) ans += (ll)(n - res + 1);
        printf("%lld\\n", ans);
    }
    return 0;
}

2. Farmer John's Cheese Block

이 문제는 3차원 공간에 NxNxN크기의 꽉 차있는 치즈블럭을 각 쿼리마다 하나씩 부셨을 때, 남은 공간에 1xN크기의 블럭이 얼마나 들어갈 수 있는 지를 각 쿼리마다 출력하는 문제이다.

N범위는 1000으로 작은편이지만 하나의 쿼리마다 3중for문을 돌면서 검사하기에는 쿼리의 개수가 최대 2x$10^5$임으로 오래걸린다.

나는 이 문제를 check배열을 이용해서 풀었다. 좌표쌍을 xy, xz, yz로 묶어 초반에미리 N으로 초기화를 해놓고 쿼리에서 주어진 좌표쌍 x, y, z에서 checkxy[x][y]—, checkxz[x][z]—, checkyz[y][z]—를 해준뒤, 0이 되었다면 ans를 1씩늘려주는 방식으로 구현하였다.

code

#include <stdio.h>
#include <algorithm>

using namespace std;

int chxy[1010][1010];
int chxz[1010][1010];
int chyz[1010][1010];
int n, q;

int main()
{
    int i, j;
    scanf("%d %d", &n, &q);
    for(i=0;i<n;i++) {
        for(j=0;j<n;j++) {
            chxy[i][j] = n;
            chxz[i][j] = n;
            chyz[i][j] = n;
        }
    }
    int ans = 0;
    while(q--) {
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        chxy[x][y]--;
        chxz[x][z]--;
        chyz[y][z]--;
        if(chxy[x][y] == 0) ans++;
        if(chxz[x][z] == 0) ans++;
        if(chyz[y][z] == 0) ans++;
        printf("%d\\n", ans);
    }
    return 0;
}

3. It's Mooin' Time

구현이 어려웠던 문제이다. 문제에서 주어진 문자열에서 abb형태(즉, 맨 앞의 알파벳이 다르고 그 뒤는 같은 문자 2개가 연속해서 나오는 경우)의 개수가 F이상인 abb형태의 문자열을 모두 구하는 문제이다. 다만 문자열에서 1개의 문자까지는 변경이 가능하다.

이 문제는 map자료구조와 간단한 아이디어를 통해 구현이 가능하다.

a~z는 총26개의 문자로 이루어져있고, 주어진 문자열에서 문자를 한번 바뀔때, 영향을 미치는 범위는 앞뒤 2문자씩 총 5문자로 제한되어있음으로, N을 돌면서, 각 위치에서 문자를 a~z로 바꾸고, 문자가 바뀌어 영향을 미친 범위만 업데이트 해주는 식으로 구현하면 된다.

code

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

using namespace std;

int n, f;
string s;
map <string, int> mp;
set <string> ans, st;

void ReRange(int l, int r, int val)
{
    for(int i=l;i<=r - 2;i++) {
        string res;
        res += s[i];
        res += s[i + 1];
        res += s[i + 2];
        if(res[0] != res[1] && res[1] == res[2]) {
            mp[res] += val;
        }
    }
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
    int i, j;
    cin >> n >> f;
    cin >> s;
    ReRange(0, n - 1, 1);
    for(i=0;i<n;i++) {
        char now = s[i];
        map<string, int> imsi = mp;
        for(char ch = 'a';ch <= 'z';ch++) {
            int l = i - 2, r = i + 2;
            if(l < 0) l = 0;
            if(r >= n) r = n - 1;
            ReRange(l, r, -1);
            s[i] = ch;
            ReRange(l, r, 1);
            for(auto itr = mp.begin();itr != mp.end();itr++) {
                if(itr->second >= f) {
                    ans.insert(itr->first);
                }
            }
        }
        mp = imsi;
        s[i] = now;
    }
    cout << ans.size() << '\\n';
    for(auto itr = ans.begin();itr!=ans.end();itr++) {
        cout << *itr << '\\n';
    }
    return 0;
}

'USACO > Bronze' 카테고리의 다른 글

USACO 2024 January Contest  (0) 2025.01.27
USACO 2024 February Contest  (0) 2025.01.27
USACO 2023 December Contest - Bronze 풀이 & 후기  (0) 2024.09.09