[투포인터] 2531 회전초밥 C++

Seunghyeon·2023년 5월 23일

백준 문제 푼다.

목록 보기
17/21

난이도에 비해 생각을 한번 더 했던 문제였던것 같다.

처음에 벨트의 시작과 끝을 연결하는 부분이 좀 막혔었다.

for (int j = i ; j < i + k ; j ++ )
{
	// if(j >= n)
    // j와 i에서 n을 빼주는 연산을 수행함.
}

중복을 허용하지 않는 map으로 해볼까 해서 map으로 구현을 돌렸는데 시간초과가 났다.
map에 insert 하고 find 한 후 clear를 해주는 과정이 꽤나 오래 걸리는듯 했다.


풀이

위 사진은 초밥을 담은 접시들이 돌아가는 벨트를 보여준 사진이다.

  1. 배열로 구성하는데 배열의 시작과 끝이 연결되어 있다. 이 부분을 잘 생각해야 하는데 간단하다

    -> 배열 인덱스를 n으로 %연산(Modular) 해주면 된다.

  2. 먹었는지 어떻게 알것인가?

    -> 나는 visited 배열을 통해 확인했다.
    for를 돌면서 초밥을 먹었으면 초밥에 적힌 숫자에 visited를 방문처리 한다.

  3. 한 줄 확인하고 나서는 뭘 한다?
    -> 방문처리를 되돌려준다. 그래야 다음 줄 시작이 가능하다.


코드

#include <bits/stdc++.h>

using namespace std;

int n, d, k, c;
int arr[30001];
int visited[30001];
int Max;

int main()
{
	cin >> n >> d >> k >> c;

	// 배열은 컨베이어 벨트이므로 처음과 끝이 이어져있음.
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
	}


	// 연속된 k개 초밥이 종류가 가장 다양해야 하며
	// c가 안들어 있는 조합으로 선택해야 최고의 효율을 보임

	// 접시수 n 초밥 가짓 수 d 연속해서 먹는 수 k 쿠폰 번호 c

	for (int i = 0; i < n; i++)
	{
		int eat = 0;
		for (int j = i; j < i + k; j++)
		{
			if (visited[arr[j%n]] == 0)
			{
				eat++;
				visited[arr[j%n]] = 1;
			}
		}

		if (eat >= Max)
		{
			if (visited[c] == 1)
			{
				Max = eat;
			}
			else
			{
				Max = eat + 1;
			}
		}

		for (int j = i; j < i + k; j++)
		{
			visited[arr[j%n]] = 0;
		}
	}

	cout << Max << endl;

	return 0;
}

후기

profile
그냥 합니다.

0개의 댓글