[BOJ/10804/C++] 카드 역배치

SHark·2023년 2월 27일
0

BOJ

목록 보기
5/59

문제출처:https://www.acmicpc.net/problem/10804

문제

1부터 20까지 숫자가 하나씩 쓰인 20장의 카드가 아래 그림과 같이 오름차순으로 한 줄로 놓여있다. 20장의 카드에 대해 10개의 구간이 주어지면, 주어진 구간의 순서대로 위의 규칙에 따라 순서를 뒤집는 작업을 연속해서 처리한 뒤 마지막 카드들의 배치를 구하는 프로그램을 작성하시오.

조건

총 10개의 줄에 걸쳐 한 줄에 하나씩 10개의 구간이 주어진다. i번째 줄에는 i번째 구간의 시작 위치 ai와 끝 위치 bi가 차례대로 주어진다. 이때 두 값의 범위는 1 ≤ ai ≤ bi ≤ 20이다.

SOL

배열을 뒤집는 아주 좋은 예제 중 하나이다. 배열을 뒤집는 방법은 STL의 reverse 함수를 이용하는 방법도 있고, 직접 구현해서 써도된다.

이정도는 직접 구현을 해보도록 하자. for문을 이용하는 방법도 있고, while문을 이용하는 방법도 있는데 이 예제는 둘의 차이를 잘 보여주는 예제 중 하나인것 같다. 둘 다 구현해보도록 하겠다.

#include <bits/stdc++.h>
using namespace std;

int card[21];
void custom_reverse(int start, int endPoint)
{
  for (int i = 0; i < (endPoint - start + 1) / 2; i++)
  {
    swap(card[start + i], card[endPoint - i]);
  }
}

int main()
{

  for (int i = 1; i <= 20; i++)
    card[i] = i;
  for (int i = 1; i <= 10; i++)
  {
    int start, endPoint;
    cin >> start >> endPoint;
    custom_reverse(start, endPoint);
  }
  for (int i = 1; i <= 20; i++)
  {
    cout << card[i] << " ";
  }
  return 0;
}

for문에서는 반복하는 횟수 부분인 (endPoint - start+1)/2 이 부분이 이해가 안갈 수 도 있다. 이 부분은 , start,end까지의 배열크기의 중간까지 라는 뜻이다.
예를들어, arr[5]~arr[10]까지면, 5,6,7,8,9,10 으로 6개가 있을거고, 중간지점까지면 반복을 총 3번을 돌아야한다. 따라서, 중간까지의 반복횟수를 구하고 싶으면 위의 식을 주로 쓴다.

위의 식이 기억이 안나면, while로 짜보면 직관적이긴하다. start<=endPoint 즉, 스타트를 하나씩 키우고 endPoint를 하나씩 줄여가면서, start가 endPoint를 넘는 그 지점이 중간지점이 될테니 , 거기까지라는 뜻이다.

#include <bits/stdc++.h>
using namespace std;

int main()
{
  int card[21];
  int start, endPoint;
  for (int i = 1; i < 21; i++)
  {
    card[i] = i;
  }
  for (int i = 0; i < 10; i++)
  {
    cin >> start >> endPoint;
    while (start <= endPoint)
    {
      swap(card[start], card[endPoint]);
      start++;
      endPoint--;
    }
  }
  for (int i = 1; i < 21; i++)
    cout << card[i] << " ";
  return 0;
}

for은 횟수를 정량적으로 나타낼 수 있을 때 유리한 반복문이고, while은 조건으로 반복횟수를 나타낼 수 있을 때, 유리하다. while과 for은 둘 다 서로 바꿔서 쓸 수 있기 때문에 ,사실 취향에 맞는거 쓰면된다.

0개의 댓글