반응형

음수가 있는지 모르고 엄청 헤맨 문제;;


첫째 줄에 수의 개수 N(1<=N<=1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 절대값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다. 라는 문구를 제대로 이해하지 못했다.

즉, 음수도 가능하다는 얘기


그렇다면 음수와 양수를 어떻게 나눌 것인가에 대한 문제가 생긴다. 

배열 위치는 항상 양수만 가능하기 때문에 (arr[-900]같은 음수들은 존재 불가)

나는 0~1000000까지는 음수를 저장하는 변수로 1000001~2000000 은 양수를 저장하는 변수로 만들었다.

처음에 1000000을 더해주고 결과를 낼때는 1000000을 빼주면 된다.

예를들어) -1000000은 Arr[0]에 저장되고, 나올때 -1000000의 값을 빼기때문에 결과는 큰 상관이 없다.


그리고 Count Sorting을 이용하여 문제를 풀었다.



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
import java.io.FileInputStream;
import java.util.Scanner;
 
public class Main {
    public static void main(String args[]) throws Exception {
        // Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
 
        Integer a=  null;
        int N = sc.nextInt();
        int size = 2000000;
        int[] arr = new int[size + 5];
        for (int i = 1; i <= N; i++) {
            //Count Sorting... 해당 값의 위치를 1로 바꿔준다.
            //음수가 있기 때문에 1000000을 더해준다.
            arr[sc.nextInt() + 1000000= 1;
        }
        for (int i = 0; i <= size; i++) {
            //모두 출력했는데 계속해서 반복문을 돌 수 있으니깐 N==0일때 종료되게 해준다.
            if(N==0break;
            //Count Sorting이기 때문에 배열이 0이면 넘어간다. 
            if (arr[i] != 0) {
                System.out.println(i-1000000);
                N--;
            }
        }
    }
}
cs


반응형
반응형

문제에 나와있는대로 

1. 첫 번째 조각의 수가 두 번째 수보다 크다면, 둘의 위치를 서로 바꾼다.

2. 두 번째 조각의 수가 세 번째 수보다 크다면, 둘의 위치를 서로 바꾼다.

3. 세 번째 조각의 수가 네 번째 수보다 크다면, 둘의 위치를 서로 바꾼다.

4. 네 번째 조각의 수가 다섯 번째 수보다 크다면, 둘의 위치를 서로 바꾼다.

5. 만약 순서가 1, 2, 3, 4, 5 순서가 아니라면 1 단계로 다시 간다.

의 규칙대로 진행해주면 된다.

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
import java.io.FileInputStream;
import java.util.*;
 
public class Main {
    public static void main(String args[]) throws Exception {
        // Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
 
        int[] arr = new int[5];
        int[] answer = new int[5];
 
        for (int i = 0; i < 5; i++) {
            arr[i] = sc.nextInt();
        }
 
        while (check(arr)) {
            // 1vs2, 2vs3, 3vs4, 4vs5 비교
            for (int x = 0; x <= 3; x++) {
                // 앞의 숫자가 크고 정렬되지 않았다면 swap한다.
                if (compare(arr, x, x + 1&& check(arr)) {
                    swap(arr, x, x + 1);
                    print(arr);
                }
            }
        }
 
    }
 
    // x번째와 y번째 값 바꾸기
    public static void swap(int[] arr, int x, int y) {
        int swap;
        swap = arr[x];
        arr[x] = arr[y];
        arr[y] = swap;
    }
 
    // x번째와 y번째 값 비교하기
    public static boolean compare(int[] arr, int x, int y) {
        if (arr[x] > arr[y]) {
            return true;
        }
        return false;
    }
 
    // 나무조각 5개이기 때문에 1,2,3,4,5 로 정렬됐는지 체크
    public static boolean check(int[] arr) {
        boolean flags = false;
        for (int i = 0; i < 5; i++) {
            if (arr[i] != (i + 1)) {
                flags = true;
                break;
            }
        }
        return flags;
    }
    //출력문
    public static void print(int[] arr) {
        for (int i = 0; i < 5; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
 
    }
}
 
cs


반응형
반응형

1자리 수 일때는 1 만 올 수 있다. (1개)

2자리 수 일때는 10 만 올 수 있다. (1개)

3자리 수 일때는 101, 100 이 올 수 있다. (2개)

4자리 수 일때는 1010, 1000, 1001 이 올 수 있다. (3개)

5자리 수 일때는 10100, 10101, 10000, 10001, 10010 이 올 수 있다. (5개)

6자리 수 일때는 101000, 101001, 101010, 100000, 100001, 100010, 100100, 100101 이 올 수 있다. (8개)


어느 정도 규칙이 보이지 않는가? 1 - 1 - 2- 3- 5- 8 - ???

안 보인다면 7자리 수일떄도 해보겠다.


1010000, 1010001, 1010010, 1010100, 1010101, 1000000, 1000001, 1000010, 1000100, 1000101, 1001000, 1001001, 1001010 (13개)


이정도면 보였으리라 생각한다. 피보나치의 규칙을 갖고 있다.

피보나치의 규칙을 이용해서 문제를 풀면 끝!


사실 이문제는 끝자리가 0으로 끝나는 dp[N][0], 1로 끝나는 dp[N][1] 로 푸는게 맞다.

앞의 수가 0일때는 0,1이 둘다 올수 있고 앞의수가 1일때는 0밖에 못오니깐..

아무튼 쉬운 경로로 풀면 되긴 하지만, 좀 더 직관적으로 보이는 뒤의 방법을 이용하는 것이 좋아보인다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.FileInputStream;
import java.util.*;
public class Main {
    public static void main(String args[]) throws Exception {
        // Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
        int N = sc.nextInt();
        int[] arr = new int[N];
        if (N == 1) {
            arr[0= 1;
        } else if (N == 2) {
            arr[1= 1;
        } else {
            arr[0= 1;
            arr[1= 1;
            for (int i = 2; i < N; i++) {
                arr[i] = arr[i - 1+ arr[i - 2];
            }
        }
        System.out.println(arr[N-1]);
    }
}
 
cs


반응형
반응형

Comparator 를 이용한 문제 

Compartor 안에 조건문을 걸어주고 return 시켜 주면 이중, 삼중으로 정렬 할 수 있다.

return 값에서 x,y 부분을 반대로 바꿔주면 [오름차순 <-> 내림차순] 으로 바꿀 수 있다.


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
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
 
public class Main {
 
    public static void main(String args[]) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        String[][] arr = new String[N][4];
        for (int i = 0; i < N; i++) {
            arr[i] = br.readLine().split(" ");
        }
        
        //Comparator 사용
        Arrays.sort(arr, new Comparator<String[]>() {
            @Override
            public int compare(String[] s1, String[] s2) {
                if (Integer.parseInt(s1[1]) == Integer.parseInt(s2[1])) {
                    if (Integer.parseInt(s1[2]) == Integer.parseInt(s2[2])) {
                        if (Integer.parseInt(s1[3]) == Integer.parseInt(s2[3])) {
                            
                            //국영수 점수가 같다면 사전 오름차순
                            return s1[0].compareTo(s2[0]);
                        }
        
                        //국어점수 같고 영어점수 같을 때, 수학 점수는 내림차순
                        return Integer.compare(Integer.parseInt(s2[3]), Integer.parseInt(s1[3]));
 
                    }
                    //국어 점수 같을 때, 영어 점수는 오름차순
                    return Integer.compare(Integer.parseInt(s1[2]), Integer.parseInt(s2[2]));
                }
                //국어점수는 내림차순
                return Integer.compare(Integer.parseInt(s2[1]), Integer.parseInt(s1[1]));
            }
 
        });
        for (int i = 0; i < N; i++) {
            System.out.println(arr[i][0]);
 
        }
    }
}
cs


반응형
반응형

알고리즘 분류로 정렬 문제를 풀고있는데 이문제는 정렬의 문제가 아닌거 같다.

가장 중요한건 long 변수를 사용해야 한다는 점?

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
import java.io.FileInputStream;
import java.util.*;
 
public class Main {
    public static void main(String args[]) throws Exception {
        // Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
        int N = sc.nextInt();
        // 0 이상 1,000,000,000 이하의 정수 이기떄문에 long 변수 사용
        long[] arr = new long[N];
        long sum = 0;
 
        for (int i = 0; i < N; i++) {
            arr[i] = sc.nextLong();
        }
 
        // 정렬 안했고 2중 반복문을 통해서 절대값으로 처리해서 계산했다.
        // i == j 일때 처리하지 않은 이유는 어차피 arr[i] - arr[j] 는 0이 되기 때문
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                sum += Math.abs(arr[i] - arr[j]);
            }
        }
        System.out.println(sum);
    }
}
 
cs


반응형
반응형

1931 문제를 풀고 난 후 푸니까 매우 쉬웠다.

Comparator를 사용한 정렬을 했다.

아래는 1931 문제에서 Comparator를 사용한 내용

그리고 11650 좌표정렬하기 1 번이랑 문제가 또오오오옥같다. (x좌표랑 y좌표만 바꾸면 됨)

-------------------------------------1931------------------------------------- 

이때, 나는 Comparator를 이용해 정렬을 했다.

정렬을 할 때 

1 1                0 1

1 1      --->      1 1

0 1      --->      1 1

2 3                2 3


처럼 정렬이 되어야 하는데 기본 Comparator 에서는 정렬되지 않기 때문에

동일 시 되었을 경우 앞에 값을 우선으로 하는 start[1] ==end[1] 이라는 조건을 넣어

종료시간 정렬 후 종료 시간이 같을 경우, 시작시간에 따라 다시 한번 정렬을 했다.

-------------------------------------1931------------------------------------- 

11651 좌표 정렬하기 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
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) throws Exception {
 
        Scanner sc = new Scanner(System.in);
 
        int N = sc.nextInt();
        int[][] arr = new int[N][2];
        for (int i = 0; i < N; i++) {
            arr[i][0= sc.nextInt();
            arr[i][1= sc.nextInt();
        }
 
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] x, int[] y) {
                if(x[1]==y[1]){
                    return Integer.compare(x[0], y[0]);
                }
                return Integer.compare(x[1], y[1]);
            }
        });
 
        for (int i = 0; i < N; i++) {
            System.out.println(arr[i][0+ " " + arr[i][1]);
        }
    }
 
}
cs


반응형
반응형

계속 해서 Comparator를 사용해서 문제를 풀고 있다. 으흠


1. 맨처음 나이순으로 정렬한다.

끝이다.

그 다음 가입한 순서대로 정렬을 해야하는데 들어온 순서가 가입한 순서기 때문에 이미 정렬이 되서 들어왔다.

단순히 String[][] 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
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
 
public class Main {
    public static void main(String args[]) throws Exception {
        //Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
 
        int N = sc.nextInt();
        String[][] arr = new String[N][2];
        for(int i=0; i<N; i++){
            arr[i][0= sc.next();
            arr[i][1= sc.next();
        }
        
        
        Arrays.sort(arr,new Comparator<String[]>(){
            @Override
            public int compare(String[] one, String[] two){
                return Integer.compare(Integer.parseInt(one[0]),Integer.parseInt(two[0]));
            }
        });
        
        for(int i=0; i<N; i++){
            System.out.println(arr[i][0+" "+ arr[i][1]);
        }
    }
}
 
cs


반응형
반응형

1931 문제를 풀고 난 후 푸니까 매우 쉬웠다.

Comparator를 사용한 정렬을 했다.

아래는 1931 문제에서 Comparator를 사용한 내용

-------------------------------------1931------------------------------------- 

이때, 나는 Comparator를 이용해 정렬을 했다.

정렬을 할 때 

1 1                0 1

1 1      --->      1 1

0 1      --->      1 1

2 3                2 3


처럼 정렬이 되어야 하는데 기본 Comparator 에서는 정렬되지 않기 때문에

동일 시 되었을 경우 앞에 값을 우선으로 하는 start[1] ==end[1] 이라는 조건을 넣어

종료시간 정렬 후 종료 시간이 같을 경우, 시작시간에 따라 다시 한번 정렬을 했다.

-------------------------------------1931------------------------------------- 


11650 좌표 정렬하기 <소스코드>

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
 
public class Main {
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        int N = Integer.parseInt(br.readLine().trim());
        int[][] arr = new int[N][2];
        String[] str = new String[2];
        for (int i = 0; i < N; i++) {
            str = br.readLine().split(" ");
            arr[i][0=Integer.parseInt(str[0]);
            arr[i][1= Integer.parseInt(str[1]);
        }
 
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] x, int[] y) {
                if (x[0== y[0]) {
                    return Integer.compare(x[1], y[1]);
                }
                return Integer.compare(x[0], y[0]);
            }
 
        });
 
        for (int i = 0; i < N; i++) {
            System.out.println(arr[i][0+ " " + arr[i][1]);
        }
 
    }
 
}
cs


반응형
반응형

Comparator 가 부족한것 같아서 Compartor를 이용해서 문제를 풀었다.

Comparator에서 int, float, char 등은 원시적인 데이터등은 정렬이 되지 않고 Object등만 정렬 가능하다. (String, Integer 등등)

그런데 원시적인 데이터의 2차 배열은 객체인가보다.. int[][]는 Comparator를 통해 정렬을 할 수 있다.  너므 어려운것...

나는 그래서 이문제를 Comparator를 통해 풀고자 int배열이 아닌 Integer 배열을 사용했다.


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
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
 
public class Main {
    static boolean[][] arr;
    static int[][] kevin;
    static int[] bacon;
    static int n;
    static int m;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
        String str = br.readLine();
        int size = str.length();
        Integer[] arr = new Integer[size];
        for (int i = 0; i < size; i++) {
            arr[i] = str.charAt(i) - '0';
        }
        // Comparator를 사용하기 위해 객체인 Integer 변수를 사용
        Arrays.sort(arr,new Comparator<Integer>(){
            @Override
            public int compare(Integer x, Integer y){
                //x,y 값으로 놓으면 오름차순이다. 나는 y,x로 놓아서 내림차순으로 바꾸었다.
                return Integer.compare(y, x);
            }
        });
        //for-each
        for(Integer i:arr){
            System.out.print(i);
        }
        
    }
 
}
cs


반응형
반응형

나처럼 Comparator를 사용해서 푼 사람은 많이 없는거 같아서 나한텐 어려웠던 문제

푸는 방법) 

끝난 시간이 빠를 수록 다음 시작시간이 빠르기 때문에 2차원 배열을 정렬한다.

다음 제일 빨리 시작하는 회의를 선택한다. (끝나는 시간도 제일 빠르다. 이미 정렬을 해 놨으므로)

차례대로 마지막까지 반복한다.


1. 시작시간 - 종료시간 을 arr[][] 배열에 저장한다.

2. arr[][] 배열을 종료시간에 따라 정렬한다.

이때, 나는 Comparator를 이용해 정렬을 했다.

정렬을 할 때 

1 1                0 1

1 1      --->      1 1

0 1      --->      1 1

2 3                2 3


처럼 정렬이 되어야 하는데 기본 Comparator 에서는 정렬되지 않기 때문에

동일 시 되었을 경우 앞에 값을 우선으로 하는 start[1] ==end[1] 이라는 조건을 넣어

종료시간 정렬 후 종료 시간이 같을 경우, 시작시간에 따라 다시 한번 정렬을 했다.


3. 정렬이 되었다면, 종료시간과 다음에 올 시작시간을 비교하면 된다.

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
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Comparator;
 
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) throws Exception {
 
        Scanner sc = new Scanner(new FileInputStream("input.txt"));
        int N = sc.nextInt();
        int[][] arr = new int[N][2];
        for (int i = 0; i < N; i++) {
            arr[i][0= sc.nextInt();
            arr[i][1= sc.nextInt();
 
        }
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] start, int[] end) {
                //start[0], end[0] 배열은 arr[][] 의 첫번째 라인(시작시간)이다.
                //start[1], end[0] 배열은 arr[][] 의 두번째 라인(종료시간)이다.
                if(start[1]==end[1]){
                    //만약 비교하는 값의 종료시간이 같을 경우 시작시간으로 정렬한다.
                    return Integer.compare(start[0], end[0]);
                }
                //종료시간에 따라 정렬한다.
                return Integer.compare(start[1], end[1]);
            }
 
        });
        
 
        int count = 0;    // 최대값 변수 
        int end = -1;    // 다음시작 시간과 비교할 변수
        for (int i = 0; i < N; i++) {
            //현재 시작시간이 이전 종료시간보다 늦을 경우 
            if (arr[i][0>= end) {
                //System.out.println(arr[i][0] + " " + arr[i][1]);
                end = arr[i][1];    //현재 종료시간을 다음 시작시간과 비교하기위해 저장 
                count++;
            }
        }
        System.out.println(count);
    }
}
 
cs



반응형

+ Recent posts