땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • I
  • ㅗ
  • D
  • 이것이 리눅스다 with Rocky Linux9
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원
Algorithm/Algorithm Problem

백준 3967 매직 스타(DFS)

Algorithm/Algorithm Problem

백준 3967 매직 스타(DFS)

2022. 9. 16. 12:35
 

3967번: 매직 스타

매직 스타의 모양이 주어진다. 수가 채워져 있지 않은 곳은 x로, 채워져 있는 곳은 'A'부터 'L'까지 알파벳으로 채워져 있다. i번째 알파벳은 숫자 i를 의미한다. '.'는 매직 스타의 형태를 만들기

www.acmicpc.net

문제는 어렵지 않았지만 시간초과에 대해서 많이 고전한 문제다.

단순히 빈칸에 대해서 사용할 수 있는 알파벳을 하나씩 넣어보고(완전탐색) 합이 26이 되면 종료하는 문제

 

근데 여기서 문제는 완전탐색을 해버리겠다고 한다면 빈칸에 대해서 넣어볼 수 있는 알파벳 여러개를 한번씩 모두 넣어본다는 것(순열)인데 이 문제는 그런 모든 경우를 구하는 문제가 아니다.

 

아래 코드에 보면 DFS의 재귀부분에 break;를 넣었는데 이 부분이 매우 핵심적인 부분이다.

 

문제에서 사전순으로 나올 수 있는 정답 하나를 바로 출력하는 것이기 때문에 빈칸 x에 대해서 알파벳을 하나 넣었으면 그 자리에 대해서 더이상 고려를 해줄 필요가 없다.

 

이 부분을 break 안해주고 계속 for를 반복해서 하나씩 넣어보는 행위(순열)을 한다면 무조껀 시간초과!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;


public class Main_3967 {
	static int[][] line_idx_list = {
			{2,3,4,5},{5,7,10,12},{2,6,9,12},{8,9,10,11},{1,3,6,8},{1,4,7,11}
	};
	static boolean[] visited = new boolean[12];
	static boolean checked = false;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int[] data = new int[12];

		int idx = 0;
		
		for (int i = 0; i < 5; i++) {
			String input = br.readLine();
			for (int j = 0; j < 9; j++) {
				if (input.charAt(j) != '.') {
					if (input.charAt(j) == 'x') {
						data[idx++] = -1;
					}
					else {
						data[idx++] = input.charAt(j) - 'A';
						visited[input.charAt(j) - 'A'] = true;
					}
				}
			}
		}


		dfs(data);
		
	}
	

	public static void dfs(int[] data) {

		if (end_check(data)) {
			if (line_check(data)) {
				draw(data);
				System.exit(0);
				}

			return; 
		}

		//순열을 만드는 코드라고 생각함
		//하지만 문제는 순열처럼 순서를 요구하는게 아닌 단순히 사전적으로 나오게 하는것이 목적
		for(int i = 0; i < 12; i++) {
			if(visited[i]) 
				continue;		
			for (int j = 0; j < 12; j++) {
				if (data[j] == -1) {
					data[j] = i;
					visited[i] = true;
					dfs(data);
					data[j] = -1;
					visited[i] = false;
					break; //따라서 순열을 만들지말고 그 자리에 값을 넣었으면 그 자리에 대한 재귀는 바로 끝내버리기
				}
			}

			
		}
	}
	
	public static boolean end_check(int[] data) {
		for (int i = 0; i < 12; i++) {
			if (data[i] == -1)
				return false;
		}
		return true;
	}
	
	public static boolean line_check(int[] data) {
		for (int i = 0; i < 6; i++) {
			int sum = 0;
			for (int j = 0; j < 4; j++) {
				sum += data[line_idx_list[i][j]-1];
			}
			if (sum != 22) //26-4
				return false;
		}
		return true;
	}
	
	private static void draw(int[] data) {
		int index = 0;
		for(int line = 0; line < 5; line++) {
			if (line == 0 || line == 4) {
				for(int i = 0; i < 9; i++) {
					if(i == 4) {
						System.out.print((char) (data[index++] + 65));
					}
					else {
						System.out.print(".");
					}
				}
			}
			else if(line == 1 || line ==3) {
				for(int i = 0; i < 9; i++) {
					if(i % 2 == 1) {
						System.out.print((char) (data[index++] + 65));
					}
					else {
						System.out.print(".");
					}
				}
			}
			else if(line == 2) {
				for(int i = 0; i < 9; i++) {
					if(i == 2 || i == 6) {
						System.out.print((char) (data[index++] + 65));
					}
					else {
						System.out.print(".");
					}
				}
			}
			System.out.println();
		}
	}

}

'Algorithm > Algorithm Problem' 카테고리의 다른 글

백준 19238 스타트 택시(BFS, 구현)  (0) 2022.09.20
백준 2623 음악프로그램(위상정렬, DFS, BFS)  (0) 2022.09.16
백준 20055 컨베이어 벨트 위의 로봇(구현)  (0) 2022.09.03
백준 1956 운동(Floyd-Warshall)  (0) 2022.08.28
백준 1238 파티(최단경로 - 다익스트라)★★  (0) 2022.08.28
    'Algorithm/Algorithm Problem' 카테고리의 다른 글
    • 백준 19238 스타트 택시(BFS, 구현)
    • 백준 2623 음악프로그램(위상정렬, DFS, BFS)
    • 백준 20055 컨베이어 벨트 위의 로봇(구현)
    • 백준 1956 운동(Floyd-Warshall)
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.