View

 

알고리즘 분류: 트라이, 백트래킹

문제 링크: https://www.acmicpc.net/problem/9202

 

 

 

 


【 문제 】

 

  •  4*4 격자판에 알파벳들이 주어지면, 각 문자에서 8방 탐색을 해 문자열을 구성하고, 그 문자열이 찾고자 하는 문자열 리스트에 들어있는지 여부에 따라 총 점수, 가장 긴 문자열, 찾은 문자 개수를 갱신하는 문제이다.
  • 주의해야할 점은 같은 위치의 문자를 두 번 이상 사용할 수 없다(다시 방문할 수 없다)는 것, 이미 찾은 문자열에 대해서는 점수를 올리거나 문자 개수를 올리지 않는다는 점이다.

 

 


【 풀이 】

  • 찾아야 할 단어 목록을 트라이로 구성.
  • 이때 트라이 노드에 단어의 끝을 나타내는 문자인 `*` 을 넣어줬다
  • 격자판에서 인접한 문자를 고르면서 문자열을 조합해내야 하기 때문에 DFS로 문자열 구성
  • 다음 문자가 다음 트라이 노드에 있는지 없는지(없으면 그 경우는 건너뛰면 됨), 다음 좌표가 격자판을 벗어나는지, 그리고 그 곳이 방문한 곳인지를 체크하기
  • 따라서 파라미터로 다음 트라이 노드를 넘겨주면서 DFS
  • 현재 트라이 노드에 `*` 이 있으면 정답을 갱신한다. 구성한 문자열을 찾은 문자열 set에 넣고 종료는 하지 않는다
  • 재귀를 종료하지 않는 이유는 현재 발견한 문자열보다 더 긴 문자열이 목록에 포함되어 있는 경우가 있기 때문이다

 

 


 

 

【 코드 】

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class BOJ_9202 {
    static class TrieNode {
        Map<Character, TrieNode> children;

        TrieNode(){
            children=new HashMap<>();
        }
    }

    static class Trie {
        TrieNode root;

        Trie(){
            root=new TrieNode();
        }
    }

    static final int[] dy={-1,1,0,0,-1,-1,1,1};
    static final int[] dx={0,0,-1,1,-1,1,-1,1};
    static StringBuilder sb=new StringBuilder();
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    static Trie t;
    static char[][] arr;
    static boolean[][] visited;
    static Set<String> found;
    static int score;
    static String maxString="";
    static int count;

    public static void main(String[] args)throws IOException {
        t=new Trie();
        int n=Integer.parseInt(br.readLine());
        for(int i=0;i<n;i++){
            String s=br.readLine();
            TrieNode temp=t.root;
            for(int j=0;j<s.length();j++){
                temp=temp.children.computeIfAbsent(s.charAt(j),a->new TrieNode());
            }
            temp.children.put('*',new TrieNode());
        }

        br.readLine();
        int b=Integer.parseInt(br.readLine());
        for(int i=0;i<b;i++){
            score=0;
            maxString="";
            count=0;
            arr=new char[4][4];
            found=new HashSet<>();
            for(int j=0;j<4;j++){
                arr[j]=br.readLine().toCharArray();
            }
            for(int j=0;j<4;j++){
                for(int k=0;k<4;k++){
                    if(!t.root.children.containsKey(arr[j][k]))continue;

                    visited=new boolean[4][4];
                    visited[j][k]=true;
                    play(j,k,arr[j][k]+"",t.root.children.get(arr[j][k]));
                }
            }
            br.readLine();
            sb.append(score).append(" ").append(maxString).append(" ").append(count).append("\n");
        }
        System.out.print(sb);
    }

    private static void play(int y,int x,String s,TrieNode temp){
        if(temp.children.containsKey('*')&&found.add(s)){
            score+=cal(s);
            maxString=compare(maxString, s);
            count++;
        }
        for(int i=0;i<8;i++){
            int ny=y+dy[i];
            int nx=x+dx[i];

            if(ny<0||nx<0||ny>=4||nx>=4)continue;
            if(visited[ny][nx])continue;
            if(!temp.children.containsKey(arr[ny][nx]))continue;

            visited[ny][nx]=true;
            play(ny,nx,s+arr[ny][nx],temp.children.get(arr[ny][nx]));
            visited[ny][nx]=false;
        }
    }

    private static int cal(String s) {
        int size=s.length();
        if(size<3)return 0;
        else if(size<5)return 1;
        else if(size<6)return 2;
        else if(size<7)return 3;
        else if(size<8)return 5;
        return 11;
    }

    private static String compare(String s1, String s2) {
        if(s1.length()<s2.length())return s2;
        else if(s1.length()>s2.length())return s1;
        else {
            int res=s1.compareTo(s2);
            if(res<0)return s1;
            else return s2;
        }
    }
}

 

728x90

'Problem Solving > Baekjoon' 카테고리의 다른 글

[백준] 15989: 1, 2, 3 더하기 4 [Java]  (0) 2024.10.15
[백준] 19585: 전설 [Java]  (0) 2024.10.10
[백준] 28422: XOR 카드 게임  (0) 2024.04.08
[백준] 1149번: RGB거리 [C++]  (0) 2023.10.02
[백준] 7576번: 토마토 [C++]  (1) 2023.10.01
Share Link
reply
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31