#유형 : 시뮬레이션

# 규칙을 찾는데 시간이 오래 걸렸고, 메모리 생각안하고 전체 소용돌이 출력하다가 메모리 초과가 났다. 따라서 소용돌이 중 범위에 해당하는 부분만 구해서 출력을 했더니 해결하였다.

 

소용돌이 규칙

1. 시작 방향은 오른쪽, 진행 방향은 오른쪽->위쪽->왼쪽->아래->오른쪽.. 반복이다

2. 회전을 두 번 할 때마다 전진하는 길이가 늘어난다. 결국은 오른쪽과 왼쪽으로 이동 시에 길이가 1개씩 늘어나는 셈이다.

3. 소용돌이 전체를 구하면 메모리 초과가 난다. 따라서 구간에 속하는 부분만 구한다.

4. 띄어쓰기는 가장 큰 숫자의 자리수에서 해당하는 숫자의 자리수의 차이를 구한 만큼 공백을 더해줘서 출력한다.

 

예시)

1(오른쪽,1칸)->2(위쪽,1칸)->3(왼쪽,2칸)->5(아래쪽,2칸)->7(오른쪽,3칸)->10(위쪽,3칸)->13(왼쪽,4칸)->17...

 

 

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
package bj;
 
 
public class p1022 {
    static int arr[][] = new int[50][5];
    static int moveX[] = {1,0,-1,0};
    static int moveY[] = {0,-1,0,1};
    static int r1,r2,c1,c2;
    static int maxCount, maxValue=0;
    public static void main(String[] args) throws IOException {
        
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        r1 = Integer.parseInt(st.nextToken());
        c1 = Integer.parseInt(st.nextToken());
        r2 = Integer.parseInt(st.nextToken());
        c2 = Integer.parseInt(st.nextToken());
        
        maxCount = (Math.abs(r1-r2)+1* (Math.abs(c1-c2)+1);
        
        solve();
        
        int space = len(maxValue);
        for(int i=0; i<=Math.abs(r1-r2); i++) {
            for(int j=0; j<=Math.abs(c1-c2); j++) {
                int currentSpace = len(arr[i][j]);
                for(int k=0; k<space-currentSpace; k++)
                    System.out.print(" ");
                System.out.print(arr[i][j]+" ");
            }System.out.println();
        }
        
//        for(int i=0; i<50; i++) {
//            for(int j=0; j<5; j++) {
//                System.out.print(arr[i][j]+" ");
//            }System.out.println();
//        }
        
    }
    public static int len(int value) {
        int result = 0;
        while(value>=10) {
            result++;
            value/=10;
        }
        return result;
    }
    
    public static void solve() {
        int x = 0,y = 0;
        int val = 1;
        int cnt = 1;
        int d=0;
        int len=0;
        boolean visit=false;
        
        if(r1<=&& y<=r2 && c1<=&& x<=c2) {
            arr[y-r1][x-c1] = val++;
            cnt++;
            visit = true;
        }
        if(!visit)
            val++;
        
        while(cnt<=maxCount) {
            d%=4;
            if(d==0 || d==2)
                len++;
            for(int i=0; i<len; i++) {
                x += moveX[d];
                y += moveY[d];
                if(r1<=&& y<=r2 && c1<=&& x<=c2) {
                    arr[y-r1][x-c1] = val;
                    maxValue = Math.max(maxValue, val);
                    cnt++;
                }
                val++;
            }
            d++;
        }
        
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

# 유형 : 탐색 

# 난이도 : Gold V

# 쉽게 볼 수 있는 DFS 문제.. 동서남북 방문 안한 곳을 갈 때마다 확률 값을 곱해줘서 매개변수로 넘겨주면서 카운트와 이동 횟수가 일치할 때 합을 해주면 된다. 아무리 풀어도 틀리길래.. 잘 못 풀은 줄 알았는데 확률값이 동/서/남/북 순서로 들어오는데 이걸 안 보고 계속 왜 틀리지 생각했다.. 문제를 꼼꼼히 읽자....

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
package bj;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class p1405 {
    static int N;
    static int prob[] = new int[4];
    static boolean visit[][]=new boolean[30][30];
    static int moveX[] = {1,-1,0,0};
    static int moveY[] = {0,0,1,-1};
    static double result = 0;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for(int i=0; i<4; i++) {
            prob[i] = Integer.parseInt(st.nextToken());
        }
        visit[15][15]=true;
        dfs(15,15,0,1.0);
        System.out.println(String.format("%.10f", result));
    }
    
    public static void dfs(int i, int j, int cnt, double val) {
        
        if(cnt == N) {
            result += val;
            return;
        }
        
        
        
        for(int d=0; d<4; d++) {
            int newX = j + moveX[d];
            int newY = i + moveY[d];
            if(!visit[newY][newX]) {
                visit[newY][newX]=true;
                dfs(newY, newX, cnt+1, val*0.01*prob[d]);
                visit[newY][newX] = false;
            }
        }
    }
}
 
cs

#유형 : 시뮬레이션 

# 토너먼트가 진행할때마다 홀수인 경우에는 num/2 + 1 짝수일 경우에는 num/2 로 진행된다. 그러면 타겟끼리 같은 그룹인지 어떻게 체크하냐면 예를들어 1 2 3 이런 경우에 +1하고 /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
package bj;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class p1057 {
    static int N,A,B;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        A = Integer.parseInt(st.nextToken());
        B = Integer.parseInt(st.nextToken());
        int cnt = 1;
        while(true) {
            int rs1 = solve(A);
            int rs2 = solve(B);
            
            if(rs1==rs2)
                break;
            
            if(A%2==0)
                A/=2;
            else if(A%2==1) {
                A/=2;
                A++;
            }
            if(B%2==0)
                B/=2;
            else if(B%2==1) {
                B/=2;
                B++;
            }
            
            cnt++;
        }
        System.out.println(cnt);
    }
    public static int solve(int num) {
        num+=1;
        return num/2;
    }
}
 
cs

#유형 : 탐색

# 많이 어려웠던 문제... 풀다가 메모리초과, 시간초과 때문에 도저히 모르겠어서 백준님 슬라이드를 통해 이해하고 풀었다.

https://www.slideshare.net/Baekjoon/baekjoon-online-judge-1019

 

우선 시작 숫자와 마지막 숫자의 일의 자리수를 0과 9로 맞춘다.

쉽게 설명하자면 만약 10에서 29사이의 사용된 0~9 숫자를 구하면 다음과 같다.

 

10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29

일의 자리만 보면 된다. 0~9사이가 2개씩 나왔다. (2-1+1)*1 => 2

 

다른 예로, 일의 자리 기준으로 생각해보자.  1350 ~ 8739 는 (873-135+1)*1 . 따라서 arr[0~9] 에는 873-135+1 를 더할수 있다.

그 다음에는 십의 자리를 구해보면 된다. 각 숫자를 10으로 나눠준다. 135 ~ 873 를 각각  ++, -- 를 통해 140 ~ 869로 만들어준다.

140 ~ 869 는 86 - 14 + 1 을 더할수 있다. 이 때 지금 구하고 있는 숫자는 십의 자리이므로  * 10을 해줘야 한다.

 

아래의 경우에 숫자들 뒤에 0~9가 붙어있는 것이다. 따라서 10을 곱해줘야한다.

10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29

이렇게 곱하는 숫자를 10씩 곱해주고, 시작숫자와 마지막 숫자를 10으로 나눠가면서 구하면 된다.

 

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
package bj;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class p1019 {
    static int N;
    static int start,end;
    static int multi=1;
    static int arr[] = new int[10];
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        start = 1;
        end = N;
        
        
        while(start<=end) {
            
            while(start%10!=0 && start<=end) {
                solve(start);
                start++;
            }
            
            if(start>end)
                break;
            
            while(end%10!=9 && start<=end) {
                solve(end);
                end--;
            }
            start/=10;
            end/=10;
            
            
            for(int i=0; i<10; i++) {
                arr[i] += (end-start+1)*multi;
            }
            multi*=10;
            
        }
        
        for(int i=0; i<10; i++) {
            System.out.print(arr[i]+" ");
        }
    }
    private static void solve(int s) {
        // TODO Auto-generated method stub
        while(s>0) {
            arr[s%10]+=multi;
            s/=10;
        }
    }
}
 
cs

'백준' 카테고리의 다른 글

#백준_1405 미친 로봇 - Java 자바  (0) 2020.01.30
#백준_1057 토너먼트 - Java  (0) 2020.01.29
#백준_2143 두 배열의 합 - Java  (0) 2020.01.28
#백준_6603 로또 - Java  (0) 2020.01.27
#백준_1987 알파벳 - Java  (0) 2020.01.27

# 유형 : 투포인터

# upper bound, lower bound 한가지 방법과 추가로 새롭게 hashMap 을 써서 풀어보았다.

배열 사이즈가 최대 1000이라서 n^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
package bj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
 
public class Main {
    static int N,M;
    static long T;
    static long arr_1[],arr_2[];
    static long cnt=0;
    static ArrayList<Long> arrList_1 = new ArrayList<>();
    static ArrayList<Long> arrList_2 = new ArrayList<>();
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        T = Long.parseLong(br.readLine());
        N = Integer.parseInt(br.readLine());
        arr_1 = new long[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i=0; i<N; i++)
            arr_1[i] = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(br.readLine());
        arr_2 = new long[M];
        st = new StringTokenizer(br.readLine());
        for(int i=0; i<M; i++
            arr_2[i] = Integer.parseInt(st.nextToken());
        
        for(int i=0; i<N; i++) {
            long sum = 0;
            for(int j=i; j<N; j++) {
                sum += arr_1[j];
                arrList_1.add(sum);
            }
        }
        for(int i=0; i<M; i++) {
            long sum = 0;
            for(int j=i; j<M; j++) {
                sum += arr_2[j];
                arrList_2.add(sum);
            }
        }
        Collections.sort(arrList_1);
        Collections.sort(arrList_2);
        
        int left = 0;
        int right = arrList_2.size()-1;
        
        for(int i=0; i<arrList_1.size(); i++) {
            long val = T-arrList_1.get(i);
            cnt += upper_bound(0, arrList_2.size(), val) - lower_bound(0, arrList_2.size(), val);
        }
        
        System.out.println(cnt);
    }
    public static int lower_bound(int left, int right, long target) {
        while(left<right) {
            int middle=(left+right)/2;
            if(arrList_2.get(middle) < target) {
                left = middle + 1;
            }else {
                right = middle;
            }
        }
        return right;
    }
    public static int upper_bound(int left, int right, long target) {
        while(left<right) {
            int middle=(left+right)/2;
            if(arrList_2.get(middle) <= target) {
                left = middle + 1;
            }else {
                right = middle;
            }
        }
        return right;
    }
}
 
 
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
package bj;
 
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
 
public class Main {
    static int N,M;
    static long T;
    static long arr_1[],arr_2[];
    static long cnt=0;
    static ArrayList<Long> arrList_1 = new ArrayList<>();
    static ArrayList<Long> arrList_2 = new ArrayList<>();
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        T = Long.parseLong(br.readLine());
        N = Integer.parseInt(br.readLine());
        arr_1 = new long[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i=0; i<N; i++)
            arr_1[i] = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(br.readLine());
        arr_2 = new long[M];
        st = new StringTokenizer(br.readLine());
        for(int i=0; i<M; i++
            arr_2[i] = Integer.parseInt(st.nextToken());
        
        for(int i=0; i<N; i++) {
            long sum = 0;
            for(int j=i; j<N; j++) {
                sum += arr_1[j];
                arrList_1.add(sum);
            }
        }
        for(int i=0; i<M; i++) {
            long sum = 0;
            for(int j=i; j<M; j++) {
                sum += arr_2[j];
                arrList_2.add(sum);
            }
        }
        Collections.sort(arrList_1);
        Collections.sort(arrList_2);
        
        HashMap<Long, Integer> map = new HashMap<>();
        for(long i : arrList_1) {
            if(map.containsKey(i)) {
                map.put(i, map.get(i)+1);
            }else {
                map.put(i,1);
            }
        }
        for(long i : arrList_2) {
            if(map.containsKey(T-i)) {
                cnt += map.get(T-i);
            }
        }
        System.out.println(cnt);
    }
}
cs

'백준' 카테고리의 다른 글

#백준_1057 토너먼트 - Java  (0) 2020.01.29
#백준_1019 책 페이지 - Java  (0) 2020.01.29
#백준_6603 로또 - Java  (0) 2020.01.27
#백준_1987 알파벳 - Java  (0) 2020.01.27
#백준_14002 가장 긴증가하는 부분 수열 4 - Java  (0) 2020.01.26

# 유형 : 탐색, DFS

# dfs 쉬운 문제중 하나, 인덱스만 잘 설정해서 탐색돌리면 해결가능

 

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
package bj;
 
 
public class p6603_ {
    static int arr[];
    static int cnt=0;
    static int N;
    static boolean visit[];
    static ArrayList<Integer> arrList = new ArrayList<>();
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        while(N!=0) {
            arr = new int[N];
            visit = new boolean[N];
            for(int i=0; i<N; i++)
                arr[i] = Integer.parseInt(st.nextToken());
            
            for(int i=0; i<N; i++) {
                arrList.add(arr[i]);
                dfs(i);
                arrList.remove(0);
            }
            st = new StringTokenizer(br.readLine());
            N = Integer.parseInt(st.nextToken());
            System.out.println();
        }
        
    }
    public static void dfs(int index) {
        if(arrList.size() == 6) {
            for(int i=0; i<arrList.size(); i++)
                System.out.print(arrList.get(i)+" ");
            System.out.println();
            return;
        }
        
        
        for(int i=index+1; i<N; i++) {
            arrList.add(arr[i]);
            dfs(i);
            arrList.remove(arrList.size()-1);
        }
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

#유형 : DFS

#전형적인 dfs , 백트래킹 문제

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
package bj;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class p1987 {
    static int max = 0;
    static int R,C;
    static int moveX[] = {0,1,0,-1};
    static int moveY[] = {-1,0,1,0};
    static char arr[][];
    static boolean use[] = new boolean[26];
    static boolean visit[][];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        arr = new char[R][C];
        visit = new boolean[R][C];
        for(int i=0; i<R; i++) {
            String str = br.readLine();
            for(int j=0; j<C; j++) {
                arr[i][j] = str.charAt(j);
            }
        }
        visit[0][0]=true;
        int next = arr[0][0]-65;
        use[next]=true;
        dfs(0,0,1);
        
        System.out.println(max);
    }
    
    public static void dfs(int i,int j, int cnt) {
        max = Math.max(max, cnt);
        
        for(int d=0; d<4; d++) {
            int newX = j + moveX[d];
            int newY = i + moveY[d];
            
            
            if(0<=newX && newX<&& 0<=newY && newY<&& !visit[newY][newX]) {
                int next = arr[newY][newX]-65;
                if(!use[next]) {
                    visit[newY][newX] = true;
                    use[next] = true;
                    dfs(newY,newX,cnt+1);
                    use[next] = false;
                    visit[newY][newX] = false;
                }
            }
        }
    }
}
 
cs

# 유형 : 이분 탐색, LIS

# 가장 긴증가하는 부분 수열 3에서 역추적하는 배열 또는 변수를 추가하여 계산하면 된다.

테스트케이스로 

7

1 6 2 4 5 3 7 가 들어온다면 정답은 1 2 4 5 7 을 출력해야한다.

 

필자의 경우에는 기존의 리스트와 별개로 arraylist를 point형으로 한개 더 만들어서 index값과 저장되는 값을 아래와 같이 쌍으로 리스트에 넣었다.

0/1/1/2/3/2/4 

1/6/2/4/5/3/7 

이제 뒤에서부터 역추적을 해보자. 가장 maxIndex는 4이고 4->3->2->1->0(7->5->4->2->1) 순으로 maxIndex를 감소해가며 추적하는데 이 때 스택을 사용해서 push한 다음 pop하여 출력하면 편하게 결과값을 출력할 수 있다. 

 



import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;
import java.util.StringTokenizer;

public class p14002 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		int arr[] = new int[N];
		ArrayList arrList = new ArrayList<>();
		ArrayList tmp = new ArrayList<>();
		StringTokenizer st = new StringTokenizer(br.readLine());
		for(int i=0; i<N; i++)
			arr[i] = Integer.parseInt(st.nextToken());
		
		for(int i=0; i<N; i++) {
			int next = arr[i];
			if(arrList.isEmpty() || arrList.get(arrList.size()-1) < next) {
				arrList.add(next);
				tmp.add(new Point(arrList.size()-1,next));
			}else {
				int left = 0;
				int right = arrList.size()-1;
				while(left<right) {
					int middle =(left+right)/2;
					if(arrList.get(middle) < next)
						left = middle + 1;
					else
						right = middle;
				}
				arrList.set(right, next);
				tmp.add(new Point(right,next));
			}
			
		}
		
		int last = -1;
		for(int i=0; i<tmp.size(); i++) {
			last = Math.max(last, tmp.get(i).x);
		}
		
		Stack stack = new Stack<>();
		
		for(int i=tmp.size()-1; i>=0; i--) {
			if(last == tmp.get(i).x) {
				stack.add(tmp.get(i).y);
				last--;
			}
		}
		
		System.out.println(arrList.size());
		
		while(!stack.isEmpty())
			System.out.print(stack.pop()+" ");
		
	}
}

+ Recent posts