본문 바로가기

PS - 알고리즘

1055 - 끝이없음

step 1

더보기

max - min은 대략 100만큼 차이 납니다. 그럼 "i번째 문자가 무엇인가"라는 문제를 i가 min, min+1, ..., max일 때까지 해서 총 100번 물어보면 됩니다. 앞으로의 설명에서는 i번째 문자를 구하는 데에 집중하겠습니다.

step 2

더보기

$ 기호가 1개일 때와 2개일 때로 나눌 수 있습니다. $가 1개일 때 먼저 처리하겠습니다. S를 $ 기준으로 앞과 뒤로 나눌 수 있습니다. $ 앞을 (1), $ 뒤를 (2)라고 하면

 

(1) (1) (1).... (1) (1) (입력) (2) (2) (2)... (2) (2)

 

로 만들어 집니다. (1)과 (2)는 (실행시킨 횟수)만큼 반복됩니다. (1)과 (2)의 길이를 구해두면 쉽게 풀 수 있습니다.

step 3

더보기

N번 실행시켰을 때 문자열의 길이가 있고 그때 $에 해당하는 문자열의 길이 L이 있을 것입니다. 앞에서부터 문자열을 보면서 $면 L만큼, 아니면 1만큼 카운트를 증가시킵니다. 그럼 i번째 문자가 어디에 해당하는지 알 수 있습니다. 만약 그 문자가 알파벳이면 바로 출력하면 됩니다. 아래는 문제의 첫 번째 예시에서 N을 2, i를 32로 했을 때입니다.

만약 $라면 N 을 1 감소시켰을 때의 문자열에서 내가 찾으려고 한 문자가 몇 번째에 있는지 계산을 합니다. $ 이전에 문자가 몇 개가 있는지 계산하면 쉽게 알 수 있습니다.

이런 식으로 계속 진행하면 답을 구할 수 있습니다.

$기호가 2개 이상이면 프로그램을 실행시킬 때 마다 적어도 2배씩 늘어난다는 뜻입니다. 그럼 프로그램을 30번만 실행시켜도 max범위를 넘어가므로 그 이상을 볼 필요가 없습니다. N의 범위가 1000000000이지만 사실은 최대 30만큼 보면 되기 때문에 해결할 수 있습니다.

 

코드

더보기
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
char b1[100], b2[100];
int main() {
    long long int i, l1,l2,n,x,y,k,t,cnt=0,j;
    scanf(" %s %s", b1, b2);
    l1 = strlen(b1);
    l2 = strlen(b2);
    scanf("%lld", &n);
    scanf("%lld%lld", &x, &y);
    for (i = 0;i < l2;i++) {
        if (b2[i] == '$') cnt++;
    }
    if (cnt == 1) {
        long long int s = 0, e = 0;
        for (i = 0;i < l2;i++) {
            if (b2[i] == '$') {
                s = i;
                e = l2 - s - 1;
            }
        }
        for (i = x;i <= y;i++) {
            if (i > s * n + e * n + l1) {
                printf("-");
                continue;
            }
            long long int t = i;
            if (t <= s * n) {
                t--;
                t %= s;
                printf("%c", b2[t]);
            }
            else if (t <= s * n + l1) {
                t--;
                t -= s * n;
                printf("%c", b1[t]);
            }
            else {
                t -= s * n + l1;
                t--;
                t %= e;
                printf("%c", b2[s + 1 + t]);
            }
        }
        return 0;
    }
    for (i = x;i <= y;i++) {
        long long int size = l1,countt=0;
        t = i;
        for (j = 1;j <= n;j++) {
            size = size * cnt + (l2 - cnt);
            countt++;
            if (size > i) break;
        }
        if (n == countt && size < i) { printf("-"); continue; }
        for (j = 1;j <= countt;j++) {
            size = (size - (l2 - cnt)) / cnt;
            long long int p = 0;
            for (k = 0;k < l2;k++) {
                if (b2[k] == '$') p += size; else p++;
                if (p >= t) {
                    if (b2[k] != '$') {
                        printf("%c", b2[k]);
                        j = n + 10;
                    }
                    else {
                        t = t-(p - size);
                    }
                    break;
                }
            }
        }
        if (j == countt + 1) printf("%c", b1[t - 1]);
    }
    return 0;
}

'PS - 알고리즘' 카테고리의 다른 글

11873 - 최대 직사각형  (0) 2024.05.26
13537 - 수열과 쿼리 1  (0) 2024.05.26
6549 - 히스토그램에서 가장 큰 직사각형  (0) 2024.05.24
MCMF(min cut max flow)  (0) 2024.05.22
8155 - Postering  (0) 2024.05.20