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

 

3055번: 탈출

문제 사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제일 친한 친구인 비버의 굴로 가능한 빨리 도망가 홍수를 피하려고 한다. 티떱숲의 지도는 R행 C열로 이루어져 있다. 비어있는 곳은 '.'로 표시되어 있고, 물이 차있는 지역은 '*', 돌은 'X'로 표시되어 있다. 비버의 굴은 'D'로, 고슴도치의 위치는 'S'로 나

www.acmicpc.net

매 분마다 고슴도치는 현재 있는 칸과 인접한 네 칸 중 하나로 이동할 수 있다. (위, 아래, 오른쪽, 왼쪽) 물도 매 분마다 비어있는 칸으로 확장한다. 물이 있는 칸과 인접해있는 비어있는 칸(적어도 한 변을 공유)은 물이 차게 된다.

고슴도치가 안전하게 비버의 굴로 이동하기 위해 필요한 최소 시간을 구한다

-> BFS로 풀면 되겠다.

->BFS로 물이 차는 시간을 먼저 구해서 배열에 저장하고 고슴도치를 이동해야겠다.

 

풀이

  1. 입력을 받으면서 고슴도치, 비버의 좌표를 저장하고 물인 경우에는 바로 큐에 넣어준다.
  2. 물이 차는 시간을 먼저 구해서 BFS를 먼저 실행한다.
  3. 그 다음 고슴도치의 이동 시간을 계산해주기 위해 고슴도치의 위치를 큐에 넣어주고 BFS를 실행한다.
  4. 고슴도치의 이동시간과 물이 차는 시간을 비교해가며 이동한다.

 

import java.util.*;

public class Main {
	static class Pair {
		int x;
		int y;
		Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
	static int dx[] = {1, -1, 0, 0};
	static int dy[] = {0, 0, 1, -1};
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int r = sc.nextInt();
		int c = sc.nextInt();
		char map[][] = new char[r][c];
		int waterTime[][] = new int[r][c];
		int hedgehogTime[][] = new int[r][c];
		int destX=0;
		int destY=0;
		int sX=0;
		int sY=0;
		Queue<Pair> q = new LinkedList<Pair>();
		sc.nextLine();
		
        //초기화
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				waterTime[i][j] = -1;
				hedgehogTime[i][j] = -1;
			}
		}
		
		for(int i=0; i<r; i++) {
			String s = sc.nextLine();
			for(int j=0; j<c; j++) {
				map[i][j] = s.charAt(j);
				if(map[i][j] == 'S') {
					sX = i;
					sY = j;
				}
				else if(map[i][j] == '*') {
					q.offer(new Pair(i,j));
					waterTime[i][j] = 0;
				}
				else if(map[i][j] == 'D') {
					destX = i;
					destY = j;
				}
			}
		}
		
        //물이 차는 시간을 먼저 구해준다.
		while(!q.isEmpty()) {
			Pair p = q.remove();
			int x = p.x;
			int y = p.y;
			for(int k=0; k<4; k++) {
				int nx = x + dx[k];
				int ny = y + dy[k];
				if(nx < 0 || ny <0 || nx >= r || ny >= c) continue;
				if(map[nx][ny] == 'D') continue; //물은 비버굴로 못간다.
				if(map[nx][ny] != 'X' && waterTime[nx][ny] == -1) {
					q.offer(new Pair(nx, ny));
					waterTime[nx][ny] = waterTime[x][y] + 1;
				}
			}
		}
	
    	//고슴도치 이동 시간 구해준다.
		q.offer(new Pair(sX, sY));
		hedgehogTime[sX][sY] = 0;
		while (!q.isEmpty()) {
            Pair p = q.remove();
            int x = p.x;
            int y = p.y;
            for (int k=0; k<4; k++) {
                int nx = x+dx[k];
                int ny = y+dy[k];
                if (nx < 0 || nx >= r || ny < 0 || ny >= c) {
                    continue;
                }
                if (hedgehogTime[nx][ny] != -1) continue;
                if (map[nx][ny] == 'X') continue; //돌 있는 곳 못감
                
                //다음 이동할 곳의 물이 차는 시간이 고슴도치의 이동시간이 같거나 작으면 가지 못한다.
                //물이 차지 않은 곳인 경우(-1) 가 아님.
                if (waterTime[nx][ny] != -1 && hedgehogTime[x][y]+1 >= waterTime[nx][ny]) continue;
                
                hedgehogTime[nx][ny] = hedgehogTime[x][y] + 1;
                q.offer(new Pair(nx, ny));
            }
        }
		
		if(hedgehogTime[destX][destY] != -1)
			System.out.println(hedgehogTime[destX][destY]);
		else
			System.out.println("KAKTUS");
	}
}

'BOJ' 카테고리의 다른 글

[BOJ] 6588. 골드바흐의 추측  (0) 2019.06.18
[BOJ] 2609. 최대공약수와 최소공배수  (0) 2019.06.14
[BOJ] 2583. 영역 구하기  (0) 2019.05.01
[BOJ] 2606. 바이러스  (0) 2019.05.01
[BOJ] 4963. 섬의 개수  (0) 2019.05.01

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

 

2583번: 영역 구하기

첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오른쪽 위 꼭짓점의 x, y좌표값이 빈칸을 사이에 두고 차례로 주어진다. 모눈종이의 왼쪽 아래 꼭짓점의 좌표는 (0,0)이고, 오른쪽 위 꼭짓점의 좌표는(N,M)이다. 입력되는 K개의 직사각형들이 모눈종이 전체를 채우는 경우는 없다.

www.acmicpc.net

 모눈종이의 왼쪽 아래 꼭짓점의 좌표는 (0,0)이고, 오른쪽 위 꼭짓점의 좌표는(N,M)이다. 

라고 나와있지만 정확한 좌표가 중요한 것은 아니라서 그냥 신경안쓰고 풀었다.

 

풀이

  1. 사각형의 좌표를 입력받아서 사각형을 칠해준다.(1로 채운다)
  2. 직사각형 내부를 제외한 나머지 부분을 구해야 하므로 값이 0인 곳에 대해서 DFS를 실행했다.
  3. 연결요소를 구분하기 위해 연결된 부분들에 번호를 붙여준다.
  4. 각 번호가 붙여진 곳들의 개수를 세서 cnt 배열에 넣어준후 출력.

 

 

import java.util.*;

public class Main {
	static int dx[] = {0, 0, 1, -1};
	static int dy[] = {1, -1, 0, 0};
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int ans[][] = new int[n][m];
		int arr[][] = new int[n][m];
        
		for(int i=0; i<k; i++) {
			int lx = sc.nextInt();
			int ly = sc.nextInt();
			int rx = sc.nextInt();
			int ry = sc.nextInt();
			for(int j=lx; j<rx; j++) { //사각형 채우기
				for(int l=ly; l<ry; l++) {
					arr[l][j] = 1;
				}
			}
		}
        
		int count=0;
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
				if(arr[i][j] == 0 && ans[i][j] == 0){
					dfs(i,j,arr, ans, ++count, n, m); //dfs가 실행될때마다 count값 증가
				}
			}
		}	
		
		System.out.println(count);
		int cnt[] = new int[count];
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
				if(ans[i][j] != 0) {
					cnt[ans[i][j]-1] +=1;
				}
			}
		}
        
		Arrays.sort(cnt);
		for(int i=0; i<count; i++) {
			System.out.print(cnt[i]+" ");
		}
	}
    
	static void dfs(int i, int j, int[][] arr, int[][] ans, int count, int n, int m) {
		ans[i][j] = count; //번호 붙여준다
		for(int k=0; k<4; k++) {
			int x = i+dx[k];
			int y = j+dy[k];
			if(x >=0 && y>=0 && x < n && y < m) {
				if(arr[x][y] == 0 && ans[x][y] == 0) {
					dfs(x, y, arr, ans, count, n, m);
				}
			}
		}
	}
}

'BOJ' 카테고리의 다른 글

[BOJ] 2609. 최대공약수와 최소공배수  (0) 2019.06.14
[BOJ] 3055. 탈출  (0) 2019.05.01
[BOJ] 2606. 바이러스  (0) 2019.05.01
[BOJ] 4963. 섬의 개수  (0) 2019.05.01
[BOJ] 7569. 토마토 (3차원)  (0) 2019.04.30

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

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.

www.acmicpc.net

풀이

  1. 1번 컴퓨터에 연결된 컴퓨터들을 구하면 되는 연결 요소 문제이다. BFS로 풀어주면 될 것 같다.
  2. 먼저 컴퓨터들의 연결 정보를 인접리스트로 구현해준다.
  3. 1번 컴퓨터를 먼저 큐에 넣고 1번 컴퓨터와 연결된 컴퓨터들을 모두 방문 체크한다.
  4. 방문한 컴퓨터(감염된 컴퓨터) 수를 출력 (1번 컴퓨터 제외).

 

 

import java.util.*;

public class Main {
	
	static ArrayList&ltInteger>[] list;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int connect = sc.nextInt();
		list = (ArrayList[]) new ArrayList[n];
		for(int i=0; i < n; i++) {
			list[i] =  new ArrayList();
		}	
		for(int i=0; i < connect; i++) {
			int u = sc.nextInt()-1;
			int v = sc.nextInt()-1;
			list[u].add(v);
			list[v].add(u);
		}
		boolean[] check = new boolean[n];
		Queue q = new LinkedList();
		q.add(0);
		check[0] = true;
		while(!q.isEmpty()) {
			int u = q.remove();
			for(int i=0; i < list[u].size(); i++) {
				int v = list[u].get(i);
				if(check[v]) continue;
				q.add(v);
				check[v] = true;
			}
		}
		int ans = -1;
		for(int i=0; i < n; i++) {
			if(check[i]) ans++;
		}		
		System.out.println(ans);
	}

}

'BOJ' 카테고리의 다른 글

[BOJ] 3055. 탈출  (0) 2019.05.01
[BOJ] 2583. 영역 구하기  (0) 2019.05.01
[BOJ] 4963. 섬의 개수  (0) 2019.05.01
[BOJ] 7569. 토마토 (3차원)  (0) 2019.04.30
[BOJ] 7576. 토마토  (0) 2019.04.30

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

 

4963번: 섬의 개수

문제 정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오. 한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.  두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러쌓여 있으며, 지도 밖으로 나갈 수 없다. 입력 입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는

www.acmicpc.net

DFS나 BFS를 사용해서 연결 요소를 구하는 문제이다.

  1. 땅이고 아직 방문하지 않은 곳을 DFS를 통해서 모두 방문해줬다.
  2. 새로 DFS를 실핼해줄때마다 count값을 증가시킨다.

 

import java.util.*;

public class Main {
	static int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
	static int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int w = sc.nextInt();
			int h = sc.nextInt();
            
			if(w ==0 && h ==0) //종료 조건
				break;
			
            int count = 0;
			int square[][] = new int[h][w];
			boolean check[][] = new boolean[h][w];
            
			for(int i=0; i<h; i++) {
				for(int j=0; j<w; j++) {
					square[i][j] = sc.nextInt();
				}
			}
            
			for(int i=0; i<h; i++) {
				for(int j=0; j<w; j++) {
					if(square[i][j] == 1 && check[i][j] == false){ //땅인데 아직 방문하지 않았다.
						dfs(i, j, square, check, h, w);	
						count++;
					}
				}
			}
			System.out.println(count);
		}
	}
	static void dfs(int i, int j, int[][] square, boolean[][] check, int h, int w) {
		check[i][j] = true; //방문 체크
		for(int k=0; k<8; k++) {
			int x = i+dx[k];
			int y = j+dy[k];
			if(x >= 0 && y >= 0 && x &lt h && y &lt w)
				if(square[x][y] == 1 && check[x][y] == false) //땅인데 방문하지 않은 곳 방문
					dfs(x, y, square, check, h, w);
		}
	}

}
            
 

'BOJ' 카테고리의 다른 글

[BOJ] 2583. 영역 구하기  (0) 2019.05.01
[BOJ] 2606. 바이러스  (0) 2019.05.01
[BOJ] 7569. 토마토 (3차원)  (0) 2019.04.30
[BOJ] 7576. 토마토  (0) 2019.04.30
[BOJ] 11724. 연결 요소의 개수  (0) 2019.04.29

문제

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PoOKKAPIDFAUq

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

지도의 한 변의 길이 N은 3 이상 8 이하의 정수이다. (3 ≤ N ≤ 8)
최대 공사 가능 깊이 K는 1 이상 5 이하의 정수이다. (1 ≤ K ≤ 5)
지도에서 가장 높은 봉우리는 최대 5개이다.
-> 이 조건들을 통해 완전 탐색을 해도 되겠다고 생각했다.

 

 

 

위가 DFS, 아래가 DFS

예전에 BFS로 길이를 배열에 저장해가며 풀었다가 메모리를 너무 많이 사용해서 DFS로 다시 풀었다.

DFS로 푸는 게 최대 depth를 저장하면 되므로 BFS보다 더 효율적인 듯하다.

BFS로도 잘 처리해주면 될 것 같지만 문제 맥락상(?) DFS가 더 맞는 것 같다.

문제를 잘 생각하고 알고리즘 사용하자!!

 

풀이

  1. 값을 처음에 입력받으면서 가장 큰 값을 top 변수에 저장한다.
  2. 배열을 탐색하며 top값과 같은 곳의 좌표를 ArrayList에 저장한다.
  3. 모든 위치에 대해서 0번에서 K번 깎는 경우까지 모든 길이를 구해서 최댓값을 max에 저장한다.
  4. max 출력.
import java.io.*;
import java.util.*;

public class Solution {
	static class Pair {
		int x;
		int y;
		Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
    
	static int[] dx = {0,0,1,-1};
	static int[] dy = {1,-1,0,0};
	static int N, K, max;
	static int[][] map;
	static boolean[][] check;
	static ArrayList<Pair> topList;
    
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for(int tc=1; tc<=T; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			K = Integer.parseInt(st.nextToken());
			map = new int[N][N];
			topList = new ArrayList();
			
			int top = 0; //가장 높은 봉우리의 값을 저장
			for(int i=0; i<N; i++) {
				st = new StringTokenizer(br.readLine());
				for(int j=0; j<N; j++) {
					map[i][j] = Integer.parseInt(st.nextToken());
					if(top < map[i][j]) top = map[i][j];
				}
			}
			
			for(int i=0; i<N; i++) {
				for(int j=0; j<N; j++) {
					if(map[i][j] == top) topList.add(new Pair(i,j));
				}
			}
            
			max = 0;
			construct();
			System.out.println("#"+tc+" "+max);
		}
	}
	
	static void construct() {
		for(int k=0; k<=K; k++) {
			for(int i=0; i<N; i++) {
				for(int j=0; j<N; j++) {
					map[i][j] -= k;
					for(int l=0; l<topList.size(); l++) { //가장 높은 봉우리들에서부터 경로 탐색
						int x = topList.get(l).x;
						int y = topList.get(l).y;
						if(x == i && y == j) continue; //현재 탐색할 가장 높은 봉우리를 공사한 경우
						check = new boolean[N][N];
						check[x][y] = true;
						int tmp = dfs(x,y,1);
						if(tmp > max) max = tmp;
						
					}
					map[i][j] += k;
				}
			}
		}
	}
	
	static int dfs(int x, int y, int depth) {
		int d = depth;
        
		for(int i=0; i<4; i++) {
			int nx = x+dx[i];
			int ny = y+dy[i];
			if(nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
			if(check[nx][ny]) continue;
			if(map[nx][ny] >= map[x][y]) continue;
            
			check[nx][ny] = true;
			d = Math.max(d,dfs(nx,ny,depth+1));
			check[nx][ny] = false;
			
		}

		return d;
	}

}

문제

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PwGK6AcIDFAUq&categoryId=AV5PwGK6AcIDFAUq&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

 

풀이

  1. 평점을 미리 배열에 저장한다.
  2. 한 학생의 점수들이 주어질 때마다 총점을 구해서 배열에 저장한다.
  3. K번째 학생의 점수를 따로 저장해놓는다.
  4. 학생들의 점수를 저장한 배열을 정렬한 후에 K번째 학생의 점수를 찾아서 해당 index를 따로 저장한다.
  5. 위에서 저장한 index값을 (N/10)으로 나누면 평점 배열의 index가 된다. (N/10 만큼씩 동일한 평점을 받기 때문)
  6. 위에서 구한 평점 배열의 index값으로 평점 배열 값을 출력.
import java.io.*;
import java.util.*;

public class Solution {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		String[] grade = {"D0","C-","C0","C+","B-","B0","B+","A-","A0","A+"};
		for(int tc=1; tc<=T; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			int N = Integer.parseInt(st.nextToken());
			int K = Integer.parseInt(st.nextToken())-1;
			int[] total = new int[N];
            
			for(int i=0; i<N; i++) {
				st = new StringTokenizer(br.readLine());
				int midScore = Integer.parseInt(st.nextToken());
				int finalScore = Integer.parseInt(st.nextToken());
				int homework = Integer.parseInt(st.nextToken());
				total[i] = midScore*35 + finalScore*45 + homework*20; //총점의 값 자체는 중요하지 않으므로 정수형으로 곱해줬다.
			}
            
			int score = total[K];
			Arrays.sort(total);
			int index = -1;
			for(int i=0; i<N; i++) {
				if(total[i] == score) {
					index = i; //K번째 학생의 성적 위치
					break;
				}
			}
            
			int ans = index/(N/10);
			System.out.println("#"+tc+" "+grade[ans]);
			
		}
	}

}

문제

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5Pw_-KAdcDFAUq&categoryId=AV5Pw_-KAdcDFAUq&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

풀이

  1. 10개의 수라고 정해져 있으므로 10개를 입력받은 후에 정렬해준다.
  2. 맨 앞과 맨 뒤를 제외한 값들을 모두 더해서 평균을 구한다.
  3. 반올림을 위해서 실수형에서 연산한 뒤에 반올림해준 후 정수형으로 출력.
  4. 최대 수, 최소 수가 여러개 있는 경우를 고려해주지 않아도 Pass 했다.

주의할 점

소수점 첫째 자리에서 반올림한 정수를 출력한다.

 

import java.io.*;
import java.util.*;

public class Solution {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for(int tc=1; tc<=T; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			int[] arr = new int[10];
			for(int i=0; i<10; i++) {
				arr[i] = Integer.parseInt(st.nextToken());
			}
			Arrays.sort(arr);
			int sum = 0;
			for(int i=1; i<9; i++) {
				sum += arr[i];
			}
			float tmp = (float)sum/8;
			int ans = Math.round(tmp); //반올림
			System.out.println("#"+tc+" "+ans);
		}
	}

}

'SWEA > D2' 카테고리의 다른 글

[SWEA] 1976. 시각 덧셈  (0) 2019.05.02
[SWEA] 1983. 조교의 성적 매기기  (0) 2019.05.01
[SWEA] 1986. 지그재그 숫자  (0) 2019.04.30
[SWEA] 1989. 초심자의 회문 검사  (0) 2019.04.30
[SWEA] 2001. 파리 퇴치  (0) 2019.04.29

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRUN9KfZ8DFAUo

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

문제

각 변에 다음과 같이 16진수 숫자(0~F)가 적혀 있는 보물상자가 있다.

보물 상자의 뚜껑은 시계방향으로 돌릴 수 있고, 한 번 돌릴 때마다 숫자가 시계방향으로 한 칸씩 회전한다.

각 변에는 동일한 개수의 숫자가 있고, 시계방향 순으로 높은 자리 숫자에 해당하며 하나의 수를 나타낸다.

보물상자에는 자물쇠가 걸려있는데, 이 자물쇠의 비밀번호는 보물 상자에 적힌 숫자로 만들 수 있는 모든 수 중, K번째로 큰 수를 10진 수로 만든 수이다.

N개의 숫자가 입력으로 주어졌을 때, 보물상자의 비밀 번호를 출력하는 프로그램을 만들어보자.

(서로 다른 회전 횟수에서 동일한 수가 중복으로 생성될 수 있다. 크기 순서를 셀 때 같은 수를 중복으로 세지 않도록 주의한다.)

 풀이

  1. 상자의 변은 4개 이므로 N/4 만큼 회전을 하면 처음과 같은 상태가 되므로 N/4번 동안 각 변을 16진수 정수로 만들어주고(findPWD) 회전해주는(Rotate) 과정을 반복한다.
    1. 문자열을 N/4 크기만큼 잘라서 16진수 정수로 변환하여 box배열에 저장한다.
    2. box 배열에 들어있는 값이 현재 list에 존재하지 않는다면 list에 추가(중복 제거)
    3. 문자열의 마지막 문자를 맨 앞에 붙여줘서 회전을 해준다.
  2. 모든 가능한 16진수를 만들어줬으면 정렬해준 후 K번째 큰 수를 구한다.
    1. K번째 큰 수를 10진수로 변환하기 위해 먼저 String으로 변환한다.
    2. String을 다시 10진수로 변환해서 출력.

 

import java.io.*;
import java.util.*;

public class Solution {
	static int N;
	static String s;
	static ArrayList&ltInteger> list;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for(int tc=1; tc<=T; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			int K = Integer.parseInt(st.nextToken());
			s = br.readLine();
			list = new ArrayList&ltInteger>();

			for(int i=0; i<N/4; i++) {
				findPWD();
				rotate();
			}
			
			Collections.sort(list);
			String tmp = Integer.toString(list.get(list.size()-K));
			int ans = Integer.parseInt(tmp, 10);
			System.out.println("#"+tc+" "+ans);
		}
	}
	
	static void findPWD() {
		int[] box = new int[4];
		int k = N/4;
		
		int index = 0;
		for(int i=0; i<N; i+=k) {
			String tmp = s.substring(i, i+k);
			box[index++] = Integer.parseInt(tmp,16);
		}
		
		for(int i=0; i<4; i++) {
			if(!list.contains(box[i])) {
				list.add(box[i]);
			}
		}
	}
	
	static void rotate() {
		String last = s.substring(N-1);
		s = last+s.substring(0, N-1);
	}
}

+ Recent posts