문제 >> 1247. [S/W 문제해결 응용] 3일차 - 최적 경로

 

Permutation 알고리즘을 이용해 고객의 집에 대한 모든 순서를 먼저 만든다 (index 이용)

각각의 경우에 대해 거리를 계산하고, 최소값을 갱신한다.

최소값을 출력한다.

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import java.io.BufferedReader; 
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
class pair {
    int y;
    int x;
 
    public pair(int y, int x) {
        this.y = y;
        this.x = x;
    }
}
 
public class Solution1247 {
    static pair home;
    static pair company;
    static pair[] cus;
    static int ans = Integer.MAX_VALUE;
 
    public static int getDistance(pair p1, pair p2) {
        return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
    }
 
    public static void swap(int[] set, int i, int index) {
        int temp = set[i];
        set[i] = set[index];
        set[index] = temp;
    }
    
    
    static int solve(int[] set) {
        int sum=0;
        sum += getDistance(company, cus[set[0]]);
        for(int i=0;i<set.length-1;i++) {
            int idx = set[i];
            int next = set[i+1];
            sum+= getDistance(cus[idx], cus[next]);
        }
        sum+=getDistance(cus[set[set.length-1]], home);
        
        return sum;
    }
    
 
    
    public static void perm(int[] set, int size, int n, int k) {
        if (size == k) { //종료조건
            int s = solve(set);
 
            ans = ans > s? s: ans;
            return;
        }
 
        for (int i = size; i < n; i++) {
            swap(set, i, size);
            perm(set, size + 1, n, k);
            swap(set, i, size);
        }
    }
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int TC = Integer.parseInt(br.readLine());
 
        for (int tc = 1; tc <= TC; tc++) {
            int N = Integer.parseInt(br.readLine()); // 고객 수
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            int y = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            ans = Integer.MAX_VALUE;
            int[] set = new int[N];
            company = new pair(y, x);
 
            y = Integer.parseInt(st.nextToken());
            x = Integer.parseInt(st.nextToken());
            home = new pair(y, x);
 
            cus = new pair[N];
            for (int i = 0; i < N; i++) {
                y = Integer.parseInt(st.nextToken());
                x = Integer.parseInt(st.nextToken());
                cus[i] = new pair(y, x);
            }
 
            for (int i = 0; i < N; i++) {
                set[i] = i;
            }
 
            perm(set, 0, N, N);
            
            System.out.println("#"+tc + " "+ans);
 
        }
    }
}
 
cs

문제 >> 1244. [S/W 문제해결 응용] 2일차 - 최대 상금

 

그리디 알고리즘을 이용한 방법.

 

직관적이지만 예외를 발견하기가 어려워서 백트래킹을 이용해 푸는게 더 효율적일것 같다.

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.StringTokenizer;
 
public class Solution_1244 {
 
        
    
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        
        int TC = Integer.parseInt(bf.readLine()); 
        int change;
        int ans;
        
        for(int tc=1;tc<=TC;tc++) {
            StringTokenizer st = new StringTokenizer(bf.readLine()," ");
            String s = st.nextToken();
            Integer[] board = new Integer[s.length()];
            change = Integer.parseInt(st.nextToken());//교환 횟수            
                
            int[] check = new int[10];
            Arrays.fill(check, -1);
            ArrayList<Integer> al = new ArrayList<Integer>();
            for(int i=0;i<board.length;i++) { //숫자판
                board[i] = s.charAt(i)-'0';
                if(check[board[i]] != -1) { //중복된 숫자가 들어온 경우
                    //al리스트에 중복된 숫자들의 인덱스를 저장해논다.
                    if(al.isEmpty())al.add(check[board[i]]);
                    al.add(i);
                }
                else check[board[i]] = i;    
            }
            
            for(int i=0;i<board.length;i++) { //선택정렬
                if(change==0break;
                
                int maxIndex = i;
                for(int j=i;j<board.length;j++) {
                    if(board[maxIndex]<=board[j]) {
                        maxIndex = j;
                    }
                }
                if(maxIndex != i) {
                    int tmp = board[maxIndex]; //1.가장 큰 숫자위치와 가장 왼쪽 원소 swap
                    board[maxIndex]=board[i]; 
                    board[i]=tmp;
                    change --;                    
                } 
            } //end of for 선택정렬
            
            //교환횟수가 남은 경우
            
            //동일한 숫자가 존재하면, 값의 변동없이 교환회수를 감소시킬 수 있다.
            HashSet<Integer> hs = new HashSet<Integer>(Arrays.asList(board));
            
            if(hs.size() != board.length) { // 같은 숫자 존재
                /* 처음에 저장해논 중복된 숫자들의 인덱스를 이용해 
                 * 중복 숫자들과 교환된 숫자들을 추출 후, tmpArr 배열에 저장한다.
                 * 
                 * 해당 숫자들을 sort 후 다시 입력한다.
                 * 
                 * ex ) 
                 * 3 2 1 8 8 8 , 3번 교환
                 * 알고리즘에 의하면
                 * 8 8 8 1 2 3 
                 * 이 되지만, 실제 답은
                 * 8 8 8 3 2 1 이다.
                 * 즉, 중복 숫자들과 교환된 숫자들은 다시 sort 후 대입한다. 
                 */
                Integer[] tmpArr = new Integer[al.size()];
                
                for(int i=0;i<al.size();i++) {
                    tmpArr[i] = board[al.get(i)];
                }
                
                Arrays.sort(tmpArr, new Comparator<Integer>() { //내림차순 정렬
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return o2-o1;
                    }
                });
                
                int idx = 0;
                for(int i : al) {
                    board[i] = tmpArr[idx++];
                }
            }
            
            
            
            //짝수번 남았으면 무시, 홀수 번이면 1의 자리와 10의자리를 바꿔준다.
            if(change%2 == 1 && hs.size() == board.length) {
                int len = board.length-1;
                int tmp = board[len]; //1.가장 큰 숫자위치와 가장 왼쪽 원소 swap
                board[len]=board[len-1]; 
                board[len-1]=tmp;
            } 
        
            
            
            System.out.print("#"+tc+" ");
            for(int i=0;i<board.length;i++System.out.print(board[i]);
            System.out.println();
        }//end of tc
        
    }//end of main
}
 
cs

 

문제 >> 차이를 최대로

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
class pair {
    int now;
    int weight;
    public pair(int now, int weight) {
        super();
        this.now = now;
        this.weight = weight;
    }
}
 
public class Main {
    static int n,m;
    static boolean[][] map;
 
    static int[] rst;
    static Scanner sc = new Scanner(System.in);
 
    static int bfs(int start) {
        boolean[] visited = new boolean[n+1];
        Queue<pair> q = new LinkedList<pair>();
        visited[start]=true;
        q.add(new pair(start,0));
        int score=0;
        
        while(!q.isEmpty()) {
            int now = q.peek().now;
            int weight = q.peek().weight;
            score+=weight;
            q.poll();
            
            for(int i=1;i<=n;i++) {
                if(map[now][i] && !visited[i]) {
                    visited[i]=true;
                    q.add(new pair(i,weight+1));
                }
            }
        }
        
        return score;
    }
    
    public static void main(String[] args) {
        n = sc.nextInt(); // 유저의 수
        m = sc.nextInt(); // 관계 수
        
        map = new boolean[n+1][n+1];
        rst = new int[n+1];
        
        for(int i=0;i<m;i++) {
            int a=sc.nextInt();
            int b=sc.nextInt();
            
            map[a][b] = true;
            map[b][a] = true;
        }
        
        int min=Integer.MAX_VALUE;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            
            rst[i] = bfs(i);
            
            if(rst[i]<min) {
                min = rst[i];
                ans = i;
            }
        }
        
        System.out.println(ans);
        
    }//end of main
}
 
cs

문제 >> 알파벳

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
class pair {
    int now;
    int weight;
    public pair(int now, int weight) {
        super();
        this.now = now;
        this.weight = weight;
    }
}
 
public class Main {
    static int n,m;
    static boolean[][] map;
 
    static int[] rst;
    static Scanner sc = new Scanner(System.in);
 
    static int bfs(int start) {
        boolean[] visited = new boolean[n+1];
        Queue<pair> q = new LinkedList<pair>();
        visited[start]=true;
        q.add(new pair(start,0));
        int score=0;
        
        while(!q.isEmpty()) {
            int now = q.peek().now;
            int weight = q.peek().weight;
            score+=weight;
            q.poll();
            
            for(int i=1;i<=n;i++) {
                if(map[now][i] && !visited[i]) {
                    visited[i]=true;
                    q.add(new pair(i,weight+1));
                }
            }
        }
        
        return score;
    }
    
    public static void main(String[] args) {
        n = sc.nextInt(); // 유저의 수
        m = sc.nextInt(); // 관계 수
        
        map = new boolean[n+1][n+1];
        rst = new int[n+1];
        
        for(int i=0;i<m;i++) {
            int a=sc.nextInt();
            int b=sc.nextInt();
            
            map[a][b] = true;
            map[b][a] = true;
        }
        
        int min=Integer.MAX_VALUE;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            
            rst[i] = bfs(i);
            
            if(rst[i]<min) {
                min = rst[i];
                ans = i;
            }
        }
        
        System.out.println(ans);
        
    }//end of main
}
 
cs

문제 >> 세로읽기

 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
class pair {
    int now;
    int weight;
    public pair(int now, int weight) {
        super();
        this.now = now;
        this.weight = weight;
    }
}
 
public class Main {
    static int n,m;
    static boolean[][] map;
 
    static int[] rst;
    static Scanner sc = new Scanner(System.in);
 
    static int bfs(int start) {
        boolean[] visited = new boolean[n+1];
        Queue<pair> q = new LinkedList<pair>();
        visited[start]=true;
        q.add(new pair(start,0));
        int score=0;
        
        while(!q.isEmpty()) {
            int now = q.peek().now;
            int weight = q.peek().weight;
            score+=weight;
            q.poll();
            
            for(int i=1;i<=n;i++) {
                if(map[now][i] && !visited[i]) {
                    visited[i]=true;
                    q.add(new pair(i,weight+1));
                }
            }
        }
        
        return score;
    }
    
    public static void main(String[] args) {
        n = sc.nextInt(); // 유저의 수
        m = sc.nextInt(); // 관계 수
        
        map = new boolean[n+1][n+1];
        rst = new int[n+1];
        
        for(int i=0;i<m;i++) {
            int a=sc.nextInt();
            int b=sc.nextInt();
            
            map[a][b] = true;
            map[b][a] = true;
        }
        
        int min=Integer.MAX_VALUE;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            
            rst[i] = bfs(i);
            
            if(rst[i]<min) {
                min = rst[i];
                ans = i;
            }
        }
        
        System.out.println(ans);
        
    }//end of main
}
 
cs

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

[BOJ] 10819 : 차이를 최대로  (0) 2019.02.08
[BOJ] 1987 : 알파벳  (0) 2019.02.08
[BOJ] 6588 : 골드바흐의 추측  (0) 2019.02.08
[BOJ]1389: 케빈 베이컨의 6단계 법칙  (0) 2019.02.08
[정올] 1809 : 탑  (0) 2019.01.22

문제 >> 골드바흐의 추측

 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
class pair {
    int now;
    int weight;
    public pair(int now, int weight) {
        super();
        this.now = now;
        this.weight = weight;
    }
}
 
public class Main {
    static int n,m;
    static boolean[][] map;
 
    static int[] rst;
    static Scanner sc = new Scanner(System.in);
 
    static int bfs(int start) {
        boolean[] visited = new boolean[n+1];
        Queue<pair> q = new LinkedList<pair>();
        visited[start]=true;
        q.add(new pair(start,0));
        int score=0;
        
        while(!q.isEmpty()) {
            int now = q.peek().now;
            int weight = q.peek().weight;
            score+=weight;
            q.poll();
            
            for(int i=1;i<=n;i++) {
                if(map[now][i] && !visited[i]) {
                    visited[i]=true;
                    q.add(new pair(i,weight+1));
                }
            }
        }
        
        return score;
    }
    
    public static void main(String[] args) {
        n = sc.nextInt(); // 유저의 수
        m = sc.nextInt(); // 관계 수
        
        map = new boolean[n+1][n+1];
        rst = new int[n+1];
        
        for(int i=0;i<m;i++) {
            int a=sc.nextInt();
            int b=sc.nextInt();
            
            map[a][b] = true;
            map[b][a] = true;
        }
        
        int min=Integer.MAX_VALUE;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            
            rst[i] = bfs(i);
            
            if(rst[i]<min) {
                min = rst[i];
                ans = i;
            }
        }
        
        System.out.println(ans);
        
    }//end of main
}
 
cs

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

[BOJ] 1987 : 알파벳  (0) 2019.02.08
[BOJ] 10798 : 세로읽기  (0) 2019.02.08
[BOJ]1389: 케빈 베이컨의 6단계 법칙  (0) 2019.02.08
[정올] 1809 : 탑  (0) 2019.01.22
5432. 쇠막대기 자르기  (0) 2019.01.15

문제 >>  케빈 베이컨의 6단계 법칙

 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
class pair {
    int now;
    int weight;
    public pair(int now, int weight) {
        super();
        this.now = now;
        this.weight = weight;
    }
}
 
public class Main {
    static int n,m;
    static boolean[][] map;
 
    static int[] rst;
    static Scanner sc = new Scanner(System.in);
 
    static int bfs(int start) {
        boolean[] visited = new boolean[n+1];
        Queue<pair> q = new LinkedList<pair>();
        visited[start]=true;
        q.add(new pair(start,0));
        int score=0;
        
        while(!q.isEmpty()) {
            int now = q.peek().now;
            int weight = q.peek().weight;
            score+=weight;
            q.poll();
            
            for(int i=1;i<=n;i++) {
                if(map[now][i] && !visited[i]) {
                    visited[i]=true;
                    q.add(new pair(i,weight+1));
                }
            }
        }
        
        return score;
    }
    
    public static void main(String[] args) {
        n = sc.nextInt(); // 유저의 수
        m = sc.nextInt(); // 관계 수
        
        map = new boolean[n+1][n+1];
        rst = new int[n+1];
        
        for(int i=0;i<m;i++) {
            int a=sc.nextInt();
            int b=sc.nextInt();
            
            map[a][b] = true;
            map[b][a] = true;
        }
        
        int min=Integer.MAX_VALUE;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            
            rst[i] = bfs(i);
            
            if(rst[i]<min) {
                min = rst[i];
                ans = i;
            }
        }
        
        System.out.println(ans);
        
    }//end of main
}
 
cs

문제 >> 1809 : 탑



- 탑의 정보를 담는 클래스 Tower. 탑의 번호(number)와 높이(size)를 저장.

- 최종 출력할 답을 담을 list

- 입력 순서대로 스택에 넣어준다.

- 이 때 스택이 비어있다면, 현재 탑의 레이저를 수신할 수 있는 장치는 없다. ==> list에 0을 넣어준다. list.add(0)

- 스택이 비어있지 않다면 ..

  가장 위에 담아있는 tower의 정보를 peek 한다.

  만약 peek 한 tower의 size가 현재 탑보다 작다면, pop한다. (현재 tower의 높이가 더 높기 때문에, 앞으로 어떤 탑의 레이저도 수신할 수 없다.

  현재 탑의 size보다 큰(즉, 현재 탑의 레이저를 수신할 수 있는) tower가 나올때까지 pop을 반복한다.

  현재 탑의 size보다 큰 tower를 만나면, 그 tower의 number를 list에 add 해주고, 현재 탑을 push 해준다.

  만약 pop을 반복하다 스택이 비면, 현재 탑의 레이저를 수신할 수 있는 탑이 없다는 뜻이므로, list에 0을 add해주고 현재 탑을 스택에 push한다.

- 최종 list를 출력한다.


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
 
class Tower {
    int number;
    int size;
     
    public Tower(int number, int size) {
        this.number = number;
        this.size = size;
    }
}
 
public class Main {
    public static void main(String[] args) {
         
        Scanner sc = new Scanner(System.in);
         
        //int T = sc.nextInt();
         
        //for(int t=1;t<=T;t++) {
            Stack<Tower> stack = new Stack<>();
            ArrayList<Integer> list = new ArrayList<>();
            int N= sc.nextInt();// 탑의 수
            int now=0// 탑의 높이
            int idx=0;
            //int[] ans = new int[N]; //answer
            for(int i=0;i<N;i++) {
                 
                now = sc.nextInt();
                 
                if(stack.empty()) list.add(0); // 스택이 비어있으면 앞에 건물이 현재건물now보다 낮은 건물이거나 처음으로 넣는 건물
                else {
                    while(!stack.empty()) {
                         
                         
                        if(stack.peek().size < now ) { // 스택에 있는 건물이 지금 넣으려는 건물보다 낮으면  pop
                            stack.pop();
                            if(stack.empty()) list.add(0); // 낮은 건물은 계속 pop하다가 스택이 비어 있으면 리스트에 0을 추가
                             
                        } else {
                            list.add(stack.peek().number); // 스택에 있는 건물이 지금 넣으려는 건물보다 높으면 그 값을 list에 추가
                            break;
                        }
                    }
                }
                stack.push(new Tower(++idx,now));
            }
             
            //System.out.print("#"+" ");
            for(int i=0;i<list.size();i++) {
                System.out.print(list.get(i)+" ");
            }
            System.out.println();
        //}
    }
}
cs

+ Recent posts