요깨비's LAB

[백준, DFS, JAVA] P.2668 숫자 고르기 본문

알고리즘(Java)/BFS&DFS

[백준, DFS, JAVA] P.2668 숫자 고르기

요깨비 2019. 12. 5. 15:28

이번에도.. 오지게 오래 걸렸습니다... 순수 완벽하게 푼것이 아닌.. 백준 질문하기에서 반례들을 이용하면서 풀었구요..
아직도 분기 처리 조건 생각하는거랑 로직을 제대로 생각 않하고 무작정 문제에 돌입하는 것... 참 안고쳐집니다. 좀만 
풀이가 생각날 것 같으면 무조건 키보드에 손이 올라가는 이 흑우.. 처음 아이디어는 자료구조 Set 2개를 이용해서 DFS를 돌면서
각 방문 노드들을 Set에 넣어주면서 indexSet(첫째 줄 배열)이랑 valueSet(두번째 줄 배열)에 값들을 비교하면서 하려고 했는데
빛 좋은 개살구 마냥 아이디어만 좋았지 실제적으로 제 머리가 그걸 구현할 정도로 호환이 안되더군요.. 다음번에 다시 도전해서 
올리겠습니다. 그냥 함수 재귀를 이용해서 풀었습니다.

여기에서 통과 조건은 

  • Root값(시작값)과 첫번째 줄에서 가리키는 값이 같을 경우입니다.

실패 조건은

  • 첫번째 줄에서 가리키는 값이 이미 방문한 값인 경우입니다.

결국에는 첫번째줄에서 가리키는값(두번째줄의 index로 활용) -> 두번째줄에서 가리키는값(첫번째줄의 index로 활용) -> ...
의 과정을 거쳐 Root값(시작값)과 일치하느냐인지를 찾는 것 같습니다.

코드입니다.

import java.util.Scanner;

public class Main {
	public static int N;
	public static int[] arr;
	public static boolean[] visited;
	public static int[] resultList;
	public static int result = 0;

	public static void main(String[] args) {
		Scanner scr = new Scanner(System.in);

		N = scr.nextInt();
		arr = new int[101];
		visited = new boolean[101];

		for (int i = 1; i <= N; i++) {
			arr[i] = scr.nextInt();
		}

		for (int i = 1; i <= N; i++) {
			if (visited[i])
				continue;

			visited[i] = true;
			if (!dfs(i, arr[i])) {
				visited[i] = false;
			} else {
				visited[i] = true;
			}
		}

		for (int i = 1; i <= N; i++) {
			if (visited[i])
				result++;
		}

		System.out.println(result);

		for (int i = 1; i <= N; i++)
			if (visited[i])
				System.out.println(i);
	}

	public static boolean dfs(int root, int index) {
		if (arr[index] == root) {
			visited[index] = true;
			return true;
		}

		if (visited[index])
			return false;

		visited[index] = true;
		if (!dfs(root, arr[index])) {
			visited[index] = false;
			return false;
		} else {
			return true;
		}
	}
}

 

아직도 분기 조건을 주는 것과 재귀시키는 부분에서 머리가 너무 안돌아 갑니다.. 끊임없이 훈련해서 현실에서는 이성적으로 개발에서는 
기계적으로 생각할주 아는 유연한 개발자가 되도록 꾸준히 노력해야겠습니다.

Comments