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

 

SW Expert Academy

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

swexpertacademy.com

 

문자 의미
. 평지(전차가 들어갈 수 있다.)
* 벽돌로 만들어진 벽
# 강철로 만들어진 벽
- 물(전차는 들어갈 수 없다.)
^ 위쪽을 바라보는 전차(아래는 평지이다.)
v 아래쪽을 바라보는 전차(아래는 평지이다.)
< 왼쪽을 바라보는 전차(아래는 평지이다.)
> 오른쪽을 바라보는 전차(아래는 평지이다.)


다음 표는 사용자가 넣을 수 있는 입력의 종류를 나타낸다.
 

문자 동작
U Up : 전차가 바라보는 방향을 위쪽으로 바꾸고, 한 칸 위의 칸이 평지라면 위 그 칸으로 이동한다.
D Down : 전차가 바라보는 방향을 아래쪽으로 바꾸고, 한 칸 아래의 칸이 평지라면 그 칸으로 이동한다.
L Left : 전차가 바라보는 방향을 왼쪽으로 바꾸고, 한 칸 왼쪽의 칸이 평지라면 그 칸으로 이동한다.
R Right : 전차가 바라보는 방향을 오른쪽으로 바꾸고, 한 칸 오른쪽의 칸이 평지라면 그 칸으로 이동한다.
S Shoot : 전차가 현재 바라보고 있는 방향으로 포탄을 발사한다.


전차가 이동을 하려고 할 때, 만약 게임 맵 밖이라면 전차는 당연히 이동하지 않는다.

전차가 포탄을 발사하면, 포탄은 벽돌로 만들어진 벽 또는 강철로 만들어진 벽에 충돌하거나 게임 맵 밖으로 나갈 때까지 직진한다.

만약 포탄이 벽에 부딪히면 포탄은 소멸하고, 부딪힌 벽이 벽돌로 만들어진 벽이라면 이 벽은 파괴되어 칸은 평지가 된다.

강철로 만들어진 벽에 포탄이 부딪히면 아무 일도 일어나지 않는다.

게임 맵 밖으로 포탄이 나가면 아무런 일도 일어나지 않는다.

초기 게임 맵의 상태와 사용자가 넣을 입력이 순서대로 주어질 때, 모든 입력을 처리하고 나면 게임 맵의 상태가 어떻게 되는지 구하는 프로그램을 작성하라.


[입력]

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 두 정수 H, W (2 ≤ H, W ≤ 20) 이 공백으로 구분되어 주어진다.

이는 게임 맵의 높이가 H, 너비가 W임을 나타낸다.

즉, 게임 맵은 H x W크기의 격자판이다.

다음 H개의 각각의 줄에는 길이가 W인 문자열이 주어진다.

각각의 문자는 위의 게임 맵 구성 요소 표에 있는 문자들만 포함하며, 전차는 단 하나만 있다.

다음 줄에는 사용자가 넣을 입력의 개수를 나타내는 정수 N(0 < N ≤ 100) 이 주어진다.

다음 줄에는 길이가 N인 문자열이 주어진다.

각각의 문자는 위의 사용자가 넣을 수 있는 입력의 종류를 나타내는 표에 있는 문자들만 포함된다.


[출력]

각 테스트 케이스마다 ‘#x’(x는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고 한 칸을 띄운 후, 모든 입력을 처리하고 난 후의 게임 맵을 H개의 줄에 걸쳐 출력한다.

 

import java.util.Scanner;

public class Solution {
	private static void game(int i, int r, int c, char[] go, char[][] map) {
		if (i > go.length)
			return;
		char temp;
		switch (go[i - 1]) { //i는 1부터 들어오므로 index값은 i-1
		case 'U':
			map[r][c] = '^';
			if (r > 0 && map[r - 1][c] == '.') {
				temp = map[r - 1][c];
				map[r - 1][c] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r - 1, c, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'D':
			map[r][c] = 'v';
			if (r < map.length - 1 && map[r + 1][c] == '.') {
				temp = map[r + 1][c];
				map[r + 1][c] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r + 1, c, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'L':
			map[r][c] = '<';
			if (c > 0 && map[r][c - 1] == '.') {
				temp = map[r][c - 1];
				map[r][c - 1] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r, c - 1, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'R':
			map[r][c] = '>';
			if (c < map[0].length - 1 && map[r][c + 1] == '.') {
				temp = map[r][c + 1];
				map[r][c + 1] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r, c + 1, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'S':
			switch (map[r][c]) {
			case '^':
				for (int j = r - 1; j >= 0; j--) {
					if (map[j][c] == '*' || map[j][c] == '#') {
						if (map[j][c] == '*') {
							map[j][c] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case 'v':
				for (int j = r + 1; j < map.length; j++) {
					if (map[j][c] == '*' || map[j][c] == '#') {
						if (map[j][c] == '*') {
							map[j][c] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case '<':
				for (int j = c - 1; j >= 0; j--) {
					if (map[r][j] == '*' || map[r][j] == '#') {
						if (map[r][j] == '*') {
							map[r][j] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case '>':
				for (int j = c + 1; j < map[0].length; j++) {
					if (map[r][j] == '*' || map[r][j] == '#') {
						if (map[r][j] == '*') {
							map[r][j] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			}
			break;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
		int T = sc.nextInt();
		int h, w, N, car_r = 0, car_c = 0;
		char[][] map;

		for (int t = 0; t < T; t++) {
			h = sc.nextInt();
			w = sc.nextInt();
			sc.nextLine();
			map = new char[h][w];

			// 맵 초기화
			for (int i = 0; i < h; i++) {
				char[] map_init = sc.nextLine().toCharArray();
				for (int j = 0; j < w; j++) {
					map[i][j] = map_init[j];
					if (map[i][j] == '^' || map[i][j] == 'v' || map[i][j] == '<' || map[i][j] == '>') {
						car_r = i;
						car_c = j;
					}
				}
			}

			N = Integer.parseInt(sc.nextLine());
			char[] C = sc.nextLine().toCharArray();

			game(1, car_r, car_c, C, map);
			sb.append("#" + (t+1) + " ");
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					sb.append(map[i][j]);
				}
				sb.append("\n");
			}
		}
		System.out.println(sb);
	}
}

재귀함수와 swith문을 이용해 동작에 따른 작업이 수행되도록 하였습니다.

 

*game(int i, int r, int c, char[] go, char[][] map)

-매개변수

int i: 현재 수행중인 동작의 순서

int r: 전차의 현재 위치 row값

int c: 전차의 현재 위치 column값

char[] go: 동작순서가 담긴 배열

char[][] map: 맵 정보가 담긴 배열

 

-종료 조건

i>go.length =현재 수행중인 동작의 순서가 동작 전체의 길이보다 커지면 return

 

-동작

//상하좌우 case에 따라

//⑴ 전차의 방향을 바꾸고

//⑵-① 해당 방향 원소가 평지이면 이동하고, 이동한 위치에서 다음 재귀함수 호출

//⑵-② 아니라면 이동하지 않고 다음 재귀함수 호출

 

//shoot case는 전차가 바라보고 있는 방향의 case에 따라

//현재 위치에서 부터 전차가 바라보는 방향의 끝까지 탐색해

//벽돌 벽이나, 강철 벽을 만나지 않으면 아무 동작없이 현재위치에서 다음 재귀함수 호출

//벽돌 벽을 만나면 포탄은 소멸, 벽돌벽은 평지로 바꾸고 현재위치에서 다음 재귀함수 호출

//강철 벽을 만나면 포탄을 소멸, 아무 동작없이 현재위치 에서 다음 재귀함수 호출

 

 

+입력부에서 전차의 위치가 입력되면 car_r와 car_c 변수에 위치를 저장해

main 함수에서 game을 호출할 때 초기 전차의 위치를 나타내는 매개변수로 넘겨주었습니다.

 

+출력부는 StringBuilder를 사용해 TestCase마다 game 함수를 거치고 난 뒤의 map 함수를 이중for문으로 탐색해 출력해주었습니다.

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

 

SW Expert Academy

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

swexpertacademy.com

 

[제약 사항]

한 막대에서 출발한 가로선이 다른 막대를 가로질러서 연속하여 이어지는 경우는 없다.

[입력]

입력 파일의 첫 번째 줄에는 테스트 케이스의 번호가 주어지며, 바로 다음 줄에 테스트 케이스가 주어진다.

총 10개의 테스트 케이스가 주어진다.

[출력]

#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 도착하게 되는 출발점의 x좌표를 출력한다.

 

import java.io.IOException;
import java.util.Scanner;

public class Ladder1 {
	private static int ladder(int r, int c, int dir, int[][] arr) { // 행, 열, arr
		// 종료 조건 row가 0일 때
		if (r == 0)
			return c;
		// 반복
		// 좌우 탐색 (온 방향으로 다시 되돌아가면 안되므로 direction 체크)
		// dir=0 -> 아래쪽에서 옴
		// dir=1 -> 왼쪽에서 옴
		// dir=2 -> 오른쪽에서 옴
		if ((c > 0 && arr[r][c - 1] == 1 && dir != 1) || (c < 99 && arr[r][c + 1] == 1 && dir != 2))
			return (c > 0 && arr[r][c - 1] == 1 && dir != 1) ? ladder(r, c - 1, 2, arr) : ladder(r, c + 1, 1, arr);
		return ladder(r - 1, c, 0, arr);
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
		int[][] arr = new int[100][100];
		int T = 10;
		int Testcase_num;
		for (int i = 0; i < T; i++) {
			// 입력부
			Testcase_num = sc.nextInt(); // 테스트 케이스 번호
			for (int j = 0; j < 100; j++) {
				for (int k = 0; k < 100; k++) {
					arr[j][k] = sc.nextInt();
				}
			}
			// 로직
			for (int j = 0; j < 100; j++) {
				if (arr[99][j] == 2) {
					sb.append("#" + Testcase_num + " " + ladder(99, j, 0, arr) + "\n");
					break;
				}
			}
		}
		// 출력부
		System.out.println(sb);
	}
}

 

사다리 타기 - 목적지부터 역순으로 재귀 탐색으로 접근하는 풀이입니다.

 

*ladder(int r, int c, int dir, int[][] arr)

-매개변수

int r= 탐색 기준 원소의 row

int c = 탐색 기준 원소의 column

int dir = 탐색 기준 원소가 온 방향

int[][] arr = 탐색할 사다리값 배열

 

-종료조건

탐색 기준 원소 row 가 0일 때 -> 해당 원소의 column 값을 리턴

 

-동작

// 좌우 탐색 (온 방향으로 다시 되돌아가면 안되므로 direction 체크)
// dir=0 -> 아래쪽에서 옴
// dir=1 -> 왼쪽에서 옴
// dir=2 -> 오른쪽에서 옴

//(배열의 index를 벗어나지 않게하는 조건) and (왼쪽(또는 오른쪽) 원소가 유효값인지 검사하는 조건) and (되돌아 가지 않게 하기 위한 조건) 코드의 색이 해당하는 조건과 동일하니 필요 시 참고하시면 되겠습니다. 
if ((c > 0 && arr[r][c - 1] == 1 && dir != 1) || (c < 99 && arr[r][c + 1] == 1 && dir != 2)

//왼쪽 원소가 유효값이면 ladder(r,c -1,2,arr) return

//오른쪽 원소가 유효값이면 ladder(r, c + 1, 1, arr) return
return (c > 0 && arr[r][c - 1] == 1 && dir != 1) ? ladder(r, c - 1, 2, arr) : ladder(r, c + 1, 1, arr);

//왼쪽과 오른쪽에 유효값이 없으면 윗 row가 반드시 유효값이므로 return ladder(r - 1, c, 0, arr)

return ladder(r - 1, c, 0, arr);

 

 

+ 출력 String을 만드는 코드 내부에서 ladder 작업을 수행하였습니다.

ladder은 arr의 가장 마지막 row, 첫 column 에서 시작하므로 99,0을 초기 매개변수로 넣어주었습니다.

 

for (int j = 0; j < 100; j++) {
if (arr[99][j] == 2) {
sb.append("#" + Testcase_num + " " + ladder(99, j, 0, arr) + "\n");
break;
}
}

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

 

SW Expert Academy

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

swexpertacademy.com

 

[제약 사항]

가로 길이는 항상 100으로 주어진다.

모든 위치에서 상자의 높이는 1이상 100이하로 주어진다.

덤프 횟수는 1이상 1000이하로 주어진다.

주어진 덤프 횟수 이내에 평탄화가 완료되면 더 이상 덤프를 수행할 수 없으므로 그 때의 최고점과 최저점의 높이 차를 반환한다 (주어진 data에 따라 0 또는 1이 된다).

[입력]

총 10개의 테스트 케이스가 주어지며, 각 테스트 케이스의 첫 번째 줄에는 덤프 횟수가 주어진다. 그리고 다음 줄에 각 상자의 높이값이 주어진다.

[출력]

#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스의 최고점과 최저점의 높이 차를 출력한다.

 

import java.util.Arrays;
import java.util.Scanner;

public class flatten {
	private static int dump(int num, int[] arr) {
		Arrays.sort(arr);
		//종료 조건1: 덤프 횟수 끝나면 최대 높이와 최소높이 차이 return
		//종료 조건2: 덤프 횟수 이내에 평탄화가 완료되면 더이상 덤프 수행x
		if(num == 0|| arr[arr.length-1]-arr[0]<=1) 
			return arr[arr.length-1]-arr[0]; 
		//반복
		arr[arr.length-1]-=1;	//가장 높은 곳 -1
		arr[0]+=1;				//가장 낮은 곳 +1
		Arrays.sort(arr);
		return dump(num-1, arr);//dump횟수 -1하고 다시 부르기
	}
	
	public static void main(String[] args) {	
		Scanner sc = new Scanner(System.in);
		int dump_n;
		int[] arr;
		StringBuilder sb = new StringBuilder();
		//입력부
		for(int i = 0; i < 10; i++) {
			dump_n = sc.nextInt();
			arr = new int[100];
			for(int j = 0; j < 100; j++) {
				arr[j] = sc.nextInt();
			}
			sb.append("#"+(i+1)+" "+dump(dump_n, arr)+"\n");
		}
		
		//출력부
		System.out.println(sb);
	}
}

 

재귀함수를 이용해 상자의 높이를 평탄화하였습니다.

 

*dump(int num int[][] arr) 

-매개변수

int num = 수행가능한 dump 횟수

int[][] arr = dump를 실행할 대상 배열

 

-종료조건

⑴ 종료 조건: 덤프 횟수 끝나면 최대 높이와 최소높이 차이를 return

⑵ 종료 조건: 덤프 횟수 이내에 평탄화가 완료되면 더이상 덤프 수행x

 

-동작

//정렬을 미리 수행하면 최솟값, 최댓값을 찾기위한 코드를 작성하지 않고 배열의 양 끝값만 고려할 수 있습니다.

Arrays.sort(arr) = dump에 들어온 arr를 오름차순 정렬하여 제일 높은 상자의 높이 = 배열의 끝 원소값, 제일 낮은 상자의 높이 = 배열의 첫 원소값

arr[arr.length-1]-=1; //가장 높은 곳 -1
arr[0]+=1; //가장 낮은 곳 +1
Arrays.sort(arr); 
return dump(num-1, arr);//dump횟수 -1하고 다시 dump 재귀함수 호출

 

https://swexpertacademy.com/main/code/problem/problemDetail.do

 

SW Expert Academy

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

swexpertacademy.com

[제약사항]

달팽이의 크기 N은 1 이상 10 이하의 정수이다. (1 ≤ N ≤ 10)


[입력]

가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.

각 테스트 케이스에는 N이 주어진다.


[출력]

각 줄은 '#t'로 시작하고, 다음 줄부터 빈칸을 사이에 두고 달팽이 숫자를 출력한다.

(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)

 

import java.util.Scanner;

public class Solution {
	static void printRowArray(int[][] arr, int r, int c, StringBuilder sb) {
		if (r == arr.length - 1 && c == arr[0].length - 1) { // 종료 조건 보통..젤 앞에
			sb.append(arr[r][c]);
			return;
		}
		if (c < arr[0].length) { 
			sb.append(arr[r][c] + " ");
			printRowArray(arr, r, c + 1, sb);
		} else { // 다음 row
			sb.append("\n");
			printRowArray(arr, r + 1, 0, sb);
		}

	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
		int T = sc.nextInt();
		int n;
		int[][] arr = null;
		int a;
		int last_row;
		int last_column;
		for (int i = 0; i < T; i++) {
			n = sc.nextInt();
			arr = new int[n][n];
			a=0;
			for (int k = 0; k < n; k++) {	// 첫줄
				arr[0][k] = ++a;
				
			}
			
			last_row = 0;
			last_column=n-1;
			
			for (int k = 1; n - k > 0; k++) {	
				int temp = n - k;
				if (k % 2 == 1) {
					for (int l = 0; l < temp; l++) {		// 아래쪽으로
						arr[++last_row][last_column] = ++a;
					}
					for (int l = 0; l <temp; l++) {	//왼쪽으로
						arr[last_row][--last_column] = ++a;
					}
				} else {			
					for (int l = 0; l <temp; l++) {		// 위쪽으로
						arr[--last_row][last_column] = ++a;
					}
					for (int l = 0; l <temp; l++) {	//오른쪽으로
						arr[last_row][++last_column] = ++a;
					}
				}
			}
			sb.append("#" + (i + 1) + "\n");
			printRowArray(arr, 0, 0, sb);
			sb.append("\n");
		}
		System.out.println(sb);
	}
}

 

규칙: n*n 배열인 경우 ⑴처음 n번의 값 대입 이후, ⑵[↓←],[↑→]의 순서로 n-1개, n-1개, n-2개, n-2개, …, 2개, 2개, 1개, 1개 의 규칙으로 값을 대입한다.

 

 

⑴ 처음 n번의 값 대입 

for (int k = 0; k < n; k++) { 
arr[0][k] = ++a;

}

//대입이 모두 끝난 후 마지막으로 값이 대입된 위치의 row와 column 값을 저장.
last_row = 0; 
last_column=n-1;

 

⑵ [↓←],[↑→]의 순서로 n-1개, n-1개, n-2개, n-2개, …, 2개, 2개, 1개, 1개 의 규칙으로 값을 대입

//↑위의 식의 n-1, n-2,…, 을 n-k로 생각하여 반복

for (int k = 1; n - k > 0; k++) { 
int temp = n - k;

// 'n-1개, n-1개, n-2개, n-2개' 처럼 같은 갯수만큼 두번씩 다른 방향으로 대입하므로

//if 조건문하나(=같은 갯수)안에

//두개의 반복문(=두번씩 다른 방향)으로 표현
if (k % 2 == 1) { //k가 홀수인 경우

//방향의 순서가 정해져있으므로 for문의 순서가 바뀌지 않도록 주의
for (int l = 0; l < temp; l++) { // 아래쪽으로
arr[++last_row][last_column] = ++a;
}
for (int l = 0; l <temp; l++) { //왼쪽으로
arr[last_row][--last_column] = ++a;
}
} else {
for (int l = 0; l <temp; l++) { // 위쪽으로
arr[--last_row][last_column] = ++a;
}
for (int l = 0; l <temp; l++) { //오른쪽으로
arr[last_row][++last_column] = ++a;
}
}
}

 

+StringBuilder와 printRowArray() 함수를 정의해 출력부 작성했습니다.

append(" ") 대신 append("\t")을 사용하면 더 깔끔한 결과를 출력할 수 있지만, SWExpertAcademy를 pass 하기 위해서는 append(" ") 를 사용하셔야 합니다.

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

 

1244번: 스위치 켜고 끄기

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩

www.acmicpc.net

입력

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩 있다. 셋째 줄에는 학생수가 주어진다. 학생수는 100 이하인 양의 정수이다. 넷째 줄부터 마지막 줄까지 한 줄에 한 학생의 성별, 학생이 받은 수가 주어진다. 남학생은 1로, 여학생은 2로 표시하고, 학생이 받은 수는 스위치 개수 이하인 양의 정수이다. 학생의 성별과 받은 수 사이에 빈칸이 하나씩 있다.

 

출력

스위치의 상태를 1번 스위치에서 시작하여 마지막 스위치까지 한 줄에 20개씩 출력한다. 예를 들어 21번 스위치가 있다면 이 스위치의 상태는 둘째 줄 맨 앞에 출력한다. 켜진 스위치는 1, 꺼진 스위치는 0으로 표시하고, 스위치 상태 사이에 빈칸을 하나씩 둔다.

 

import java.io.IOException;
import java.util.Scanner;

//백준 1244  스위치 켜고 끄기
public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt(); // 스위치 개수 T

		// 스위치 배열 입력-저장부
		boolean[] arr = new boolean[T];
		for (int i = 0; i < T; i++) {
			if (sc.nextInt() == 0)
				arr[i] = false;
			else
				arr[i] = true;
		}

		// 학생 입력부
		int stu_n = sc.nextInt();
		int[][] student = new int[stu_n][2];
		for (int i = 0; i < stu_n; i++) {
			student[i][0] = sc.nextInt();
			student[i][1] = sc.nextInt();
			if (student[i][0] == 1)
				recur_b(arr, student[i][1], 1);
			else
				recur_g(arr, student[i][1], 1);
		}
        
		//출력부
		for(int i = 0 ; i < T-1 ; i++) {
			if(arr[i])
				System.out.print(1 +" ");
			else
				System.out.print(0+" ");
			if(i%20 == 19)
				System.out.println();
		}
		if(arr[T-1])
			System.out.println(1);
		else
			System.out.println(0);

	}
    //남학생 재귀
	static void recur_b(boolean[] arr, int n, int k) { // 배열, 남학생이 받은 수 , 배수 카운트용 k
		if (n * k > arr.length) {
		} // 1.남학생이 받은 수의 배수가 스위치 arr 길이보다 커질 때-스위치 상태 변화 x
		else { // 2.남학생이 받은 수의 배수가 스위치 arr 길이보다 작을 때-스위치 상태 변화 o
			arr[n * k - 1] = !arr[n * k - 1];
			++k;
			if (n * k <= arr.length)
				recur_b(arr, n, k); // k+1 범위로 재탐색
		}
	}
	//여학생 재귀
	static void recur_g(boolean[] arr, int n, int k) { // 배열, 여학생이 받은 수 , 좌우 대칭 카운트용 k
		if (n == 1 || n == arr.length || arr[n - 1 - k] != arr[n - 1 + k]) {
			arr[n - 1] = !arr[n - 1]; // 1.여학생이 양끝 스위치 번호를 받았을 때-본인 스위치 상태만 변화o
		} else { // 2-2.좌우가 대칭일 때-스위치 상태 변화 o
			arr[n - 1 - k] = !arr[n - 1 - k];
			arr[n - 1 + k] = !arr[n - 1 + k];
			k++;
			if (n - k > 0 && n + k <= arr.length)
				recur_g(arr, n, k); // k+1 범위로 재탐색
			else
				arr[n - 1] = !arr[n - 1]; // 좌우 대칭이나 다음 재귀호출이 범위를 넘을 경우 본인 스위치 상태 변화
		}
	}

}

 

입력값에 따른 남학생 또는 여학생의 재귀 함수를 불러주었습니다.

 

*recur_b (남학생 재귀함수)

-매개변수

boolean[] arr = 배열

int n = 남학생이 받은 번호

int k = 배수 카운트용 변수

 

-종료조건

n*k > arr.length = 남학생이 받은 수의 배수가 스위치의 개수보다 커지면 -> 종료

 

-동작

arr[n * k - 1] = !arr[n * k - 1] = 스위치 상태변화

++k;
if (n * k <= arr.length)
recur_b(arr, n, k); = k+1 범위로 재탐색 

 

*recur_g(여학생 재귀함수)

-매개변수

boolean[] arr = 배열

int n = 여학생이 받은 번호

int k = 좌우 대칭 카운트용 변수

 

-종료조건

n == 1 || n == arr.length = 여학생이 양끝 스위치 번호를 받았을 때 

 arr[n - 1 - k] != arr[n - 1 + k] = 좌우 대칭이 아닐 때

-> arr[n - 1] = !arr[n - 1]; = 여학생이 받은 번호의 스위치만 상태를 바꾸고 종료

 

-동작

arr[n - k - 1] = !arr[n - k - 1]; = 왼쪽 대칭 스위치 상태변화
arr[n + k - 1] = !arr[n + k - 1]; = 오른쪽 대칭 스위치 상태변화
k++;
if (n - k > 0 && n + k <= arr.length)
recur_g(arr, n, k); // k+1 범위로 재탐색
else
arr[n - 1] = !arr[n - 1]; // 좌우 대칭이나 다음 재귀호출이 범위를 넘을 경우 본인 스위치 상태만 변화

'문제해결 > 백준' 카테고리의 다른 글

백준 1158번-요세푸스 문제(JAVA)  (1) 2021.08.10
백준 2605번-줄 세우기(JAVA)  (0) 2021.08.06
백준 2493번-탑(JAVA)  (0) 2021.08.05
백준 17298번-오큰수(JAVA)  (0) 2021.08.05
백준 2309번-일곱 난쟁이(JAVA)  (0) 2021.08.04

+ Recent posts