λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Algorithm

[λ°±μ€€] 1021번: νšŒμ „ν•˜λŠ” 큐

by 주발2 2020. 4. 7.
λ°˜μ‘ν˜•

https://www.acmicpc.net/problem/1021

 

1021번: νšŒμ „ν•˜λŠ” 큐

첫째 쀄에 큐의 크기 Nκ³Ό 뽑아내렀고 ν•˜λŠ” 수의 개수 M이 주어진닀. N은 50보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄κ³ , M은 N보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ μ€„μ—λŠ” 지민이가 뽑아내렀고 ν•˜λŠ” 수의 μœ„μΉ˜κ°€ μˆœμ„œλŒ€λ‘œ 주어진닀. μœ„μΉ˜λŠ” 1보닀 ν¬κ±°λ‚˜ κ°™κ³ , N보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

www.acmicpc.net

μ½”λ“œ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(bf.readLine());
		
		int N = Integer.parseInt(st.nextToken());	// 큐의 크기
		int M = Integer.parseInt(st.nextToken());	// 뽑아내렀고 ν•˜λŠ” 수의 개수
		int[] arr = new int[M];	// 뽑아내렀고 ν•˜λŠ” 수의 μœ„μΉ˜
		int min = 0;	// 2번, 3번 μ—°μ‚°μ˜ μ΅œμ†Ÿκ°’
		LinkedList<Integer> list = new LinkedList<Integer>();
		
		st = new StringTokenizer(bf.readLine());
		
		for(int i=0; i<M; i++) 
			arr[i] = Integer.parseInt(st.nextToken());
		
		for(int i=1; i<=N; i++)
			list.add(i);

		for(int i=0; i<arr.length; i++) {
			
			// ν˜„μž¬ 리슀트의 값이 λ°”λ‘œ 뽑아내렀고 ν•˜λŠ” κ°’μΌλ•Œ
			if(arr[i] == list.peek()) {
				list.remove();
				continue;
			}
			
			// 뽑아내렀고 ν•˜λŠ” 수λ₯Ό 2λ²ˆμ—°μ‚°(μ™Όμͺ½μœΌλ‘œ 이동)을 ν•˜λŠ” 것이 더 μ΄λ“μΌλ•Œ
			if(list.indexOf(arr[i]) <= list.size()/2 ) {
				
				// μ™Όμͺ½μœΌλ‘œ ν•œμΉΈμ”© λ°€κΈ° - ν˜„μž¬κ°’ μ œκ±°ν•˜κ³  λ§ˆμ§€λ§‰μ— λ„£κΈ°
				while(list.peek() != arr[i]) {
					int temp = list.remove();
					list.add(temp);
					min ++;
				}
			}
			
			// 뽑아내렀고 ν•˜λŠ” 수λ₯Ό 3λ²ˆμ—°μ‚°(였λ₯Έμͺ½μœΌλ‘œ 이동)을 ν•˜λŠ” 것이 더 μ΄λ“μΌλ•Œ
			else {
				
				// 였λ₯Έμͺ½μœΌλ‘œ ν•œμΉΈμ”© λ°€κΈ° - κ°€μž₯ λ§ˆμ§€λ§‰κ°’μ„ ν˜„μž¬κ°’μœΌλ‘œ λ„£κΈ°
				while(list.peek() != arr[i]) {
					int temp = list.get(list.size()-1);
					list.add(0, temp);
					list.remove(list.size()-1);
					min ++;
				}
			}
			
			list.remove();	// 뽑아내렀고 ν•˜λŠ” μˆ˜κ°€ 첫번째 μœ„μΉ˜λ‘œ 였면 뽑아낸닀.
		}
		
		System.out.println(min);
		bf.close();
	}

}

풀이

문제λ₯Ό 잘 이해해야 ν•œλ‹€. 

큐의 크기가 N개이면, 1 ~ NκΉŒμ§€μ˜ 값이 λ“€μ–΄κ°„λ‹€.

κ·Έ ν›„ 1~NκΉŒμ§€μ˜ 수 쀑 λ½‘μœΌλ €κ³  ν•˜λŠ” 개수(M)κ³Ό λ½‘μœΌλ €κ³  ν•˜λŠ” μˆœμ„œμ˜ μœ„μΉ˜κ°€ 주어진닀.

2번, 3번 연산이 μ΅œμ†Ÿκ°’μ΄ λ˜λ„λ‘ λ½‘μ•„μ•Όν•˜λŠ”λ° 2번, 3번 μ—°μ‚°μ˜ 쑰건은 λ‹€μŒκ³Ό κ°™λ‹€.

  2. μ™Όμͺ½μœΌλ‘œ ν•œ μΉΈ μ΄λ™μ‹œν‚¨λ‹€. 이 연산을 μˆ˜ν–‰ν•˜λ©΄, a1, ..., ak κ°€ a2, ..., ak, a1 이 λœλ‹€.

  3. 였λ₯Έμ‘±μœΌλ‘œ ν•œ μΉΈ μ΄λ™μ‹œν‚¨λ‹€. 이 연산을 μˆ˜ν–‰ν•˜λ©΄ a1, ..., ak κ°€ ak, a1, ..., ak-1 이 λœλ‹€.

 

즉 λ½‘μœΌλ €κ³  ν•˜λŠ” μˆœμ„œμ˜ μœ„μΉ˜κ°€ μ™Όμͺ½μœΌλ‘œ μ΄λ™μ‹œν‚€λŠ” 것이 μ΅œμ†Ÿκ°’μΈμ§€, 였λ₯Έμͺ½μœΌλ‘œ μ΄λ™μ‹œν‚€λŠ” 것이 μ΅œμ†Ÿκ°’μΈμ§€ 비ꡐ해가며 μ΅œμ†Ÿκ°’μ΄ λ‚˜μ˜€λ„λ‘ ν’€μ–΄μ•Όν•œλ‹€.

 

N = 10 μΌλ•Œ, 

list = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10] 이 λœλ‹€.

 

μ—¬κΈ°μ„œ 1 ~ 6λŠ” 2λ²ˆμ—°μ‚°(μ™Όμͺ½μœΌλ‘œ 이동)을 μˆ˜ν–‰ν•˜λŠ” 것이 μ΅œμ†Ÿκ°’μ΄κ³ ,

6 ~ 10은 3λ²ˆμ—°μ‚°(였λ₯Έμͺ½μœΌλ‘œ 이동)을 μˆ˜ν–‰ν•˜λŠ” 것이 μ΅œμ†Ÿκ°’μ΄λ‹€.

즉 λ½‘μœΌλ €κ³  ν•˜λŠ” μœ„μΉ˜μ˜ μΈλ±μŠ€κ°’μ΄ list μ‚¬μ΄μ¦ˆμ˜ λ°˜λ³΄λ‹€ μž‘κ±°λ‚˜ κ°™μ„λ•Œ -> μ™Όμͺ½μ΄λ™,

list μ‚¬μ΄μ¦ˆμ˜ λ°˜λ³΄λ‹€ ν΄λ•Œ -> 였λ₯Έμͺ½μœΌλ‘œ 이동 ν•˜λŠ”κ²ƒμ΄ μ΅œμ†Ÿκ°’μ΄ λœλ‹€.

 

μ™Όμͺ½μœΌλ‘œ μ΄λ™ν•˜λŠ” 연산은 ν˜„μž¬κ°’μ„ μ œκ±°ν•˜κ³ , μ œκ±°ν•œ ν˜„μž¬κ°’μ„ list에 λ„£μ–΄μ£Όλ©΄ λœλ‹€.

였λ₯Έμͺ½μœΌλ‘œ μ΄λ™ν•˜λŠ” 연산은 리슀트의 λ§ˆμ§€λ§‰κ°’μ„ μ œκ±°ν•˜κ³ , 리슀트의 κ°€μž₯ μ²«λ²ˆμ§Έμ— μ œκ±°ν•œ 값을 λ„£μ–΄μ£Όλ©΄ λœλ‹€.

 

 

 

 

 

λ°˜μ‘ν˜•

λŒ“κΈ€