문제 - https://www.acmicpc.net/problem/3665

 

3665번: 최종 순위

올해 ACM-ICPC 대전 인터넷 예선에는 총 n개의 팀이 참가했다. 팀은 1번부터 n번까지 번호가 매겨져 있다. 놀랍게도 올해 참가하는 팀은 작년에 참가했던 팀과 동일하다. 올해는 인터넷 예선 본부에

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringBuilder sb = new StringBuilder();
    static StringTokenizer st;

    static int N, M;
    static int[] order;
    static class Node{
        int id, oriOrder, inDegree;
        Set<Integer> outDirect;
        public Node(int id, int ord){
            this.id = id;
            this.oriOrder = ord;
            this.inDegree = ord;
            this.outDirect = new HashSet<>();
        }
    }
    static HashMap<Integer, Node> nodes;

    public static void main(String[] args) throws Exception {

        int T = Integer.parseInt(br.readLine());
        for (int i = 0; i < T; i++) {
            N = Integer.parseInt(br.readLine());
            order = new int[N];
            nodes = new HashMap<>();

            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                int id = Integer.parseInt(st.nextToken());
                order[j] = id;
                nodes.put(id, new Node(id, j));
                for (int k = 0; k < j; k++) {
                    nodes.get(order[k]).outDirect.add(id);
                }
            }

            M = Integer.parseInt(br.readLine());
            for (int j = 0; j < M; j++) {
                st = new StringTokenizer(br.readLine());
                int a = Integer.parseInt(st.nextToken());
                int b = Integer.parseInt(st.nextToken());
                swap(nodes.get(a), nodes.get(b));
            }
            sb.append(sort()+"\n");
        }

        bw.write(sb.toString());
        bw.flush();
        bw.close();
        br.close();
    }
    static void swap(Node A, Node B){
        if (!A.outDirect.contains(B.id)){
            Node tmp = A;
            A = B;
            B = tmp;
        }
        A.outDirect.remove(B.id);
        A.inDegree++;
        B.outDirect.add(A.id);
        B.inDegree--;
    }
    static String sort(){
        Queue<Node> Q = new ArrayDeque<>();
        for (Map.Entry<Integer, Node> E : nodes.entrySet()) {
            if (E.getValue().inDegree==0){
                if (Q.size()==1) return "?";
                Q.add(E.getValue());
            }
        }

        StringBuilder order = new StringBuilder();
        for (int i = 0; i < N; i++) {
            if (Q.isEmpty()) return "IMPOSSIBLE";
            Node cur = Q.poll();
            order.append(cur.id+" ");

            for (int next : cur.outDirect){
                nodes.get(next).inDegree--;
                if (nodes.get(next).inDegree == 0) Q.add(nodes.get(next));
            }
        }
        return order.toString();
    }
}

위상정렬 문제라는건 파악했지만, 정말 로직을 생각하고 구현하는데 너무너무 어려웠다...

위상정렬에 대한 부분이 많이 약한것같다! 연습하자!

'공부 > algorithm' 카테고리의 다른 글

BOJ 치즈(2636) - Java  (0) 2021.11.16
BOJ 연구소 2(17141) - Java  (0) 2021.11.16
BOJ 회의실 배정(1931) - Java  (0) 2021.10.25
BOJ 쉬운 계단 수(10844) - Java  (0) 2021.10.23
BOJ 내리막 길(1520) - Java  (0) 2021.10.20

문제 - https://www.acmicpc.net/problem/1931

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N, cnt = 0;
    static int[][] info;

    public static void main(String[] args) throws Exception {

        N = Integer.parseInt(br.readLine());
        info = new int[N][2];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            info[i][0] = Integer.parseInt(st.nextToken());
            info[i][1] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(info, (a, b) -> a[1]==b[1] ? a[0]-b[0] : a[1]-b[1]);
        int s, e = 0;
        for (int[] cur : info) {
            s = cur[0];
            if(e<=s){
                cnt++;
                e = cur[1];
            }
        }

        bw.write(cnt+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
}

종료시간이 같은 경우에 대한 예외처리를 생각하지 못하고 몇번의 제출기회를 의미없이 날렸다..

제출전에 다양한 코너케이스를 생각하는 습관을 들여야겠다!

'공부 > algorithm' 카테고리의 다른 글

BOJ 연구소 2(17141) - Java  (0) 2021.11.16
BOJ 최종 순위(3665) - Java  (0) 2021.11.16
BOJ 쉬운 계단 수(10844) - Java  (0) 2021.10.23
BOJ 내리막 길(1520) - Java  (0) 2021.10.20
BOJ RGB거리(1149) - Java  (0) 2021.10.20

문제 - https://www.acmicpc.net/problem/10844

 

10844번: 쉬운 계단 수

첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static int N;
    static long[][] nums;
    static long cnt = 0;

    public static void main(String[] args) throws Exception {

        N = Integer.parseInt(br.readLine());
        nums = new long[N][10];

        for (int i = 1; i <= 9; i++) nums[0][i] = 1; // init
        for (int row = 1; row < N; row++) {
            nums[row][0] = nums[row-1][1];
            for (int i = 1; i <= 8; i++)
                nums[row][i] = (nums[row-1][i-1] + nums[row-1][i+1]) % 1000000000;
            nums[row][9] = nums[row-1][8];
        }
        for (long i : nums[N-1])
            cnt += i;

        bw.write(cnt%1000000000+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
}

간단한 DP문제였지만, 자료형을 신경못써서 '맞는데 왜 틀렸지' 한참을 고민했다..

20억 미만이더라도 그냥 뭔가 좀 수상하다 싶으면 Long타입 쓰자!

'공부 > algorithm' 카테고리의 다른 글

BOJ 최종 순위(3665) - Java  (0) 2021.11.16
BOJ 회의실 배정(1931) - Java  (0) 2021.10.25
BOJ 내리막 길(1520) - Java  (0) 2021.10.20
BOJ RGB거리(1149) - Java  (0) 2021.10.20
BOJ 후보 추천하기(1713) - Java  (0) 2021.10.14

문제 - https://www.acmicpc.net/problem/1520

 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int M, N;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] map, dp;

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());
        map = new int[M][N];
        dp = new int[M][N];
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                dp[i][j] = -1;
            }
        }

        bw.write(dfs(0, 0)+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static int dfs(int r, int c){
        if (r==M-1 && c==N-1) // 종료지점이면
            return 1; // 1 리턴
        else if (dp[r][c]<0){ // 방문한적 없으면
            dp[r][c] = 0; // 0으로 초기화하고
            for (int i = 0; i < 4; i++) { // 4방향 돌면서
                int nr = r + dr[i];
                int nc = c + dc[i];
                if (0<=nr && nr<M && 0<=nc && nc<N && map[r][c]>map[nr][nc]) // 조건만족하면
                    dp[r][c] += dfs(nr, nc); // 값 추가
            }
        }
        return dp[r][c]; // 갈 수 있는 경로수 리턴
    }
}

단순 BFS, DFS로 2차례 시도했는데, 입력이 크지도 않은거 같은데 메모리초과가 나서 당황했다.

작은배열이더라도 메모리를 생각하는 습관을 들여야겠다!

'공부 > algorithm' 카테고리의 다른 글

BOJ 회의실 배정(1931) - Java  (0) 2021.10.25
BOJ 쉬운 계단 수(10844) - Java  (0) 2021.10.23
BOJ RGB거리(1149) - Java  (0) 2021.10.20
BOJ 후보 추천하기(1713) - Java  (0) 2021.10.14
BOJ 가르침(1062) - Java  (0) 2021.10.13

문제 - https://www.acmicpc.net/problem/1149

 

1149번: RGB거리

첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N;
    static int[][] colors, cost;

    public static void main(String[] args) throws Exception {

        N = Integer.parseInt(br.readLine());
        colors = new int[N][3];
        cost = new int[N][3];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            colors[i][0] = Integer.parseInt(st.nextToken());
            colors[i][1] = Integer.parseInt(st.nextToken());
            colors[i][2] = Integer.parseInt(st.nextToken());
        }

        cost[0] = colors[0];
        for (int i = 1; i < N; i++) {
            cost[i][0] = Math.min(cost[i-1][1] + colors[i][0], cost[i-1][2] + colors[i][0]); // R 고를때
            cost[i][1] = Math.min(cost[i-1][0] + colors[i][1], cost[i-1][2] + colors[i][1]); // G 고를때
            cost[i][2] = Math.min(cost[i-1][0] + colors[i][2], cost[i-1][1] + colors[i][2]); // B 고를때
        }

        bw.write(Math.min(Math.min(cost[N-1][0], cost[N-1][1]), cost[N-1][2])+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
}

단순한 DP였다

'공부 > algorithm' 카테고리의 다른 글

BOJ 쉬운 계단 수(10844) - Java  (0) 2021.10.23
BOJ 내리막 길(1520) - Java  (0) 2021.10.20
BOJ 후보 추천하기(1713) - Java  (0) 2021.10.14
BOJ 가르침(1062) - Java  (0) 2021.10.13
BOJ 우주 탐사선(17182) - Java  (0) 2021.10.11

문제 - https://www.acmicpc.net/problem/1713

 

1713번: 후보 추천하기

첫째 줄에는 사진틀의 개수 N이 주어진다. (1 ≤ N ≤ 20) 둘째 줄에는 전체 학생의 총 추천 횟수가 주어지고, 셋째 줄에는 추천받은 학생을 나타내는 번호가 빈 칸을 사이에 두고 추천받은 순서대

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringBuilder sb = new StringBuilder();
    static StringTokenizer st;

    static int N, R;
    static boolean[] candidates;
    static class Poster{
        int order, voted;
        public Poster(int order, int voted){
            this.order = order;
            this.voted = voted;
        }
    }
    static Map<Integer, Poster> posters = new HashMap<>();

    public static void main(String[] args) throws Exception {

        N = Integer.parseInt(br.readLine());
        R = Integer.parseInt(br.readLine());

        candidates = new boolean[R+1];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < R; i++) {
            int id = Integer.parseInt(st.nextToken());

            if (candidates[id]) // 이미 있으면
                posters.get(id).voted++; // 추천수 증가
            else if (posters.size()<N) { // 빈 액자 있으면
                posters.put(id, new Poster(i, 1)); // 새로운 후보 추가
                candidates[id] = true;
            }
            else{ // 액자에 없는데 빈 액자도 없으면
                int poster_id = 0;
                int order = Integer.MAX_VALUE;
                int voted = Integer.MAX_VALUE;
                for(Map.Entry<Integer, Poster> E : posters.entrySet()){ // 포스터 중에서
                    int K = E.getKey();
                    Poster V = E.getValue();
                    if (V.voted < voted || (voted==V.voted && V.order < order)) { // 추천수 제일 낮거나, 오래전에 등록된 후보
                        poster_id = K;
                        voted = V.voted;
                        order = V.order;
                    }
                }
                posters.remove(poster_id); // 제거
                candidates[poster_id] = false;
                posters.put(id, new Poster(i, 1)); // 새로운 후보 추가
                candidates[id] = true;
            }
        }
        for (int i = 1; i <= R; i++) {
            if (candidates[i])
                sb.append(i+" ");
        }

        bw.write(sb.toString());
        bw.flush();
        bw.close();
        br.close();
    }
}

간단한 구현문제였는데, 조건을 제대로 읽지않아서 한참을 '맞는데 왜 틀렸지..'하면서 제출기회를 많이 썼다..

문제를 똑바로 읽자!

보자마자 우선순위큐가 생각났는데.. PQ를 써도 드라마틱하게 런타임이 개선되지는 않을거같아서 그냥 배열로 풀었다.

'공부 > algorithm' 카테고리의 다른 글

BOJ 내리막 길(1520) - Java  (0) 2021.10.20
BOJ RGB거리(1149) - Java  (0) 2021.10.20
BOJ 가르침(1062) - Java  (0) 2021.10.13
BOJ 우주 탐사선(17182) - Java  (0) 2021.10.11
BOJ KCM Travel(10217) - Java  (0) 2021.10.10

문제 - https://www.acmicpc.net/problem/1062

 

1062번: 가르침

첫째 줄에 단어의 개수 N과 K가 주어진다. N은 50보다 작거나 같은 자연수이고, K는 26보다 작거나 같은 자연수 또는 0이다. 둘째 줄부터 N개의 줄에 남극 언어의 단어가 주어진다. 단어는 영어 소문

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringBuilder sb = new StringBuilder();
    static StringTokenizer st;

    static int N, K, cnt = 0;
    static boolean[] alpha = new boolean[26];
    static char[][] words;

    public static void main(String[] args) throws Exception {
        br = new BufferedReader(new InputStreamReader(new FileInputStream("./input.txt")));

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        if (K<5) sb.append(0);
        else{
            words = new char[N][];
            for (int i = 0; i < N; i++) {
                words[i] = br.readLine().toCharArray();
            }
            learn(0, K);
            sb.append(cnt);
        }

        bw.write(sb.toString());
        bw.flush();
        bw.close();
        br.close();
    }
    static void learn(int s, int remain){
        if (remain==0){
            cnt = Math.max(cnt, count());
            return;
        }
        for (int i = s; i < 26; i++) {
            if(!alpha[i]) {
                alpha[i] = true;
                learn(i+1, remain - 1);
                alpha[i] = false;
            }
        }
    }
    static int count(){
        int tmp = N;
        for (int i = 0; i < N; i++) {
            for(char c : words[i]){
                if (!alpha[c-'a']){
                    tmp--;
                    break;
                }
            }
        }
        return tmp;
    }
}

퍼포먼스가 좋지는 않다. 그러나 가장 단순한 풀이가 아닐까 싶다.

'공부 > algorithm' 카테고리의 다른 글

BOJ RGB거리(1149) - Java  (0) 2021.10.20
BOJ 후보 추천하기(1713) - Java  (0) 2021.10.14
BOJ 우주 탐사선(17182) - Java  (0) 2021.10.11
BOJ KCM Travel(10217) - Java  (0) 2021.10.10
BOJ Yonsei TOTO(12018) - Java  (0) 2021.10.04

문제 - https://www.acmicpc.net/problem/17182

 

17182번: 우주 탐사선

우주 탐사선 ana호는 어떤 행성계를 탐사하기 위해 발사된다. 모든 행성을 탐사하는데 걸리는 최소 시간을 계산하려 한다. 입력으로는 ana호가 탐색할 행성의 개수와 ana호가 발사되는 행성의 위

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringBuilder sb = new StringBuilder();
    static StringTokenizer st;

    static int N, K, mintime = 10000;
    static boolean[] visit;
    static int[][] adj, dist;

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        
        visit = new boolean[N];
        visit[K] = true;
        adj = new int[N][N];
        dist = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                adj[i][j] = Integer.parseInt(st.nextToken());
                dist[i][j] = adj[i][j];
            }
        }

        for (int k = 0; k < N; k++) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
        search(K, 0, 1);

        bw.write(mintime+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static void search(int s, int time, int visited){
        if(visited==N){
            mintime = Math.min(mintime, time);
            return;
        }

        for (int e = 0; e < N; e++) {
            if(!visit[e]) {
                visit[e] = true;
                search(e, time+dist[s][e], visited+1);
                visit[e] = false;
            }
        }
    }
}

주어진 범위가 크지 않은것을 보고 플로이드워셜 알고리즘을 이용해야 한다는것만 잘 캐치한다면, 무리없이 풀 수 있는 문제였다.

중복방문이 허용된다는 말이 함정일수도있는데, 플로이드워셜을 이용한다면 이미 중복또한 포함되어있기때문에 말그대로 최단거리가 된다.

'공부 > algorithm' 카테고리의 다른 글

BOJ 후보 추천하기(1713) - Java  (0) 2021.10.14
BOJ 가르침(1062) - Java  (0) 2021.10.13
BOJ KCM Travel(10217) - Java  (0) 2021.10.10
BOJ Yonsei TOTO(12018) - Java  (0) 2021.10.04
BOJ A와 B(12904) - Java  (0) 2021.10.04

+ Recent posts