developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • c++ 빌더 패턴
  • 시계열
  • SW역량테스트파이썬풀이
  • 통계분석
  • AR모형
  • 삼성코테자바준비
  • c++디자인패턴
  • 삼성코테구현문제추천
  • MA모형
  • 삼성코테파이썬풀이
  • 삼성코테준비
  • 삼성코테파이썬
  • 백준파이썬풀이
  • SW역량테스트파이썬
  • 코테파이썬
  • 삼성코테파이썬준비
  • 시계열분석
  • 삼성코테기출자바풀이
  • 카카오코테java풀이
  • 통계학
  • 데이터분석
  • 운영체제인터럽트
  • 삼성코테구현풀이
  • 삼성코테자바꿀팁
  • 삼성코테자바풀이
  • 삼성코테기출
  • 카카오코테
  • Arima
  • BOJ파이썬풀이
  • ARIMA모형

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 소풍 2026번 (JAVA)

2022. 8. 23. 06:12

❓ 문제 - 백준 소풍 2026번 - JAVA 풀이법

 

출처 

(https://www.acmicpc.net/problem/2026)

 

2026번: 소풍

만약 K명의 친구 관계인 학생들이 존재하지 않는다면 -1을 출력한다. 그 외의 경우에는, K개의 줄에 학생들의 번호를 증가하는 순서로 한 줄에 한 개씩 출력한다. 여러 경우가 존재한다면 첫 번째

www.acmicpc.net

 

 

📝 문제해결법

1. 문제

  • N명중에 K명을 소풍을 보내려고 선택해야한다.
  • 하지만 K명 모두 친구관계이어야 하며, 만약 K명 이상인 친구관계가 존재하지 않으면 -1을 여러 개라면 번호가 작은 순서대로 K개까지만 출력해야 한다.

 

2. 해결 방법

  • 우선 인접행렬로 서로의 친구관계를 표시하고, 백트래킹을 통해 조건에 맞는 경우를 구해서 k명을 선발할 수 있을지 따져본다.
  • 하지만 단순 백트래킹으로 풀면 시간초과가 발생한다.
  • 따라서 백트래킹을 처음 들어가는 main 부분에서 각 사람마다 친구의 명수를 배열에 저장한 뒤, 해당 사람의 친구가 만약 k명보다 작다면 계산할 필요가 없으므로 조건을 걸어둔다. 
  • 그리고 백트래킹으로 구하다가 이미 선발된 인원이 k명이 채워진다면 c가 true로 바꿔서 이미 선택이 완료된 경우 재귀에 들어가지 못하도록 조건을 걸어둔다.

 

 

3. 삽질 & 느낀점

  • 여러 조건을 걸었는데도 자꾸 시간초과가 발생하고 게시판에 있는 모든 반례를 돌렸는데 통과했다.
  • 하지만 알고 보니깐 dfs 내에서의 조건보다 백트래킹을 시작하는 입구부분에서 맨 처음의 사람이 친구가 k명 이상이 되는지 여부에 따라서도 재귀를 탈지말지 결정하는 부분이 중요 포인트였던 것이었다.
  • 앞으로 백트래킹을 풀 때 dfs 내에 조건 뿐만 아니라 밖에서의 조건도 고려해서 문제를 풀어봐야겠다고 느꼈다.

 

💻 소스코드 (JAVA)

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

public class Main_2026 {
    public static int k, n, f;
    public static boolean c = false;
    public static boolean[][] check;
    public static int[] friend_num;
    public static int[] friend;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        k = Integer.parseInt(st.nextToken());
        n = Integer.parseInt(st.nextToken());
        f = Integer.parseInt(st.nextToken());
        check = new boolean[n+1][n+1];
        friend_num = new int[n+1];
        for(int i=0;i<f;i++){
            st = new StringTokenizer(br.readLine(), " ");
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            check[a][b] = true;
            check[b][a] = true;
            friend_num[a]++;
            friend_num[b]++;
        }
        friend = new int[k];
        boolean[] visited = new boolean[n+1];

        for(int i=1;i<=n;i++) {
            if(friend_num[i] < (k-1)) continue;
            dfs(1, i, visited);
            if(c) break;
        }
        if(!c) System.out.println(-1);
    }

    public static void dfs(int depth, int node, boolean[] visited){
        if(c) return;
        visited[node] = true;
        if(depth == k){
            c = true;
            for(int i=1;i<=n;i++){
                if(visited[i])
                    System.out.println(i);
            }
            return;
        }
        for(int i=1;i<=n;i++){
            if(visited[i] || !check[node][i]) continue;
            if(c) return;
            if(i != node && isfriend(visited, i)){
                dfs(depth+1, i, visited);
            }
        }
        visited[node] = false;
        return;

    }

    public static boolean isfriend(boolean[] visited, int node){
        for(int i=1;i<=n;i++){
            if(visited[i]){
                if(!check[i][node]) return false;
            }
        }
        return true;
    }

}

 

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 정육면체 9029번 (JAVA)  (0) 2022.08.28
BOJ - 친구 네트워크 4195번 (JAVA)  (0) 2022.08.25
BOJ - 악덕 영주 혜유 20010번 (JAVA)  (0) 2022.08.16
BOJ - 견우와 직녀 16137번 (JAVA)  (0) 2022.08.04
BOJ - 숫자구슬 2613번 (JAVA)  (0) 2022.07.30
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 정육면체 9029번 (JAVA)
    • BOJ - 친구 네트워크 4195번 (JAVA)
    • BOJ - 악덕 영주 혜유 20010번 (JAVA)
    • BOJ - 견우와 직녀 16137번 (JAVA)
    developer-ellen
    developer-ellen

    티스토리툴바