본문 바로가기
알고리즘/백준

[백준 22858] 원상 복구 (small) (C++)

by fortissimo 2024. 10. 6.

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