https://www.acmicpc.net/problem/22858
문제
P1, P2, ⋯, PN의 수가 적혀 있는 N개의 카드가 있다.
1부터 N까지 수가 하나씩 존재하는 수열 D1, D2, ⋯,Di, ⋯, DN이 있다. 이때 각 i에 대해 Di번째 카드를 i번째로 가져오는 작업을 셔플이라고 부른다.
예를 들어, P1, P2, ⋯, PN이 1, 4, 5, 3, 2이고, D1, D2, ⋯, DN가 4, 3, 1, 2, 5라고 가정해보자. 이 카드를 한번 섞으면 3, 5, 1, 4, 2가 된다. 아래 그림에서 S는 카드를 한 번 섞은 후를 의미한다.
위 방식을 그대로 K번 셔플한 카드의 정보와 D의 정보를 알고 있다고 할 때, 원래 카드는 어떤 배치를 이루고 있었는지 구해보자.
입력
첫번째 줄에는 카드의 개수 N과 카드를 섞은 횟수인 K가 공백으로 구분되어 주어진다.
두번째 줄에는 K번 카드를 섞은 후 카드의 배치를 의미하는 Si가 공백으로 구분되어 총 N개 주어진다.
세번째 줄에는 총 N개의 Di이 공백으로 구분되어 주어진다.
출력
원래 카드의 배치인 P1부터 PN까지의 값들을 공백으로 구분해서 출력한다.
제한
- 1 ≤ N ≤ 104
- 1 ≤ K ≤ 103
- 1 ≤ Di ≤ N
- 1 ≤ Pi, Si ≤ 106
- Pi는 정수
문제 풀이
구현 문제.
P의 D[i]번째 카드가 S의 i번째 카드가 된다. 따라서 D[i]로부터 S[i]의 원래 인덱스를 얻을 수 있고, 원소 자체의 값은 S[i]이다. 임시 배열 temp를 만들어 이전 과정이었을 배열을 저장하며, 셔플 이전의 상태를 여러 번 거쳐 원래의 P가 되도록 이를 K번 반복해주면 된다.
아래는 코드.
더보기
더보기
#include <iostream>
using namespace std;
int main()
{
cin.tie(NULL);
ios::sync_with_stdio(false);
int N, M;
cin >> N >> M;
int* P = new int[N];
int* D = new int[N];
int* temp = new int[N];
for (int i = 0; i < N; i++)
{
cin >> P[i];
}
for (int i = 0; i < N; i++)
{
cin >> D[i];
temp[i] = 0;
}
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
int index = D[j] - 1;
temp[index] = P[j];
}
for (int j = 0; j < N; j++)
{
P[j] = temp[j];
}
}
for (int i = 0; i < N; i++)
{
cout << temp[i] << " ";
}
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 10431] 줄세우기 (C++) (0) | 2024.10.08 |
---|---|
[백준 31589] 포도주 시음 (C++) (0) | 2024.10.07 |
[백준 21318] 피아노 체조 (C++) (0) | 2024.10.05 |
[백준 14916] 거스름돈 (C++) (0) | 2024.10.04 |
[백준 11507] 카드셋트 (C++) (0) | 2024.10.03 |