swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV15Khn6AN0CFAYD
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
문제를 보면서 처음 한 생각.
완탐이 가능한가? => 최대 6C2(15)^10 => 안돼.
하고 어떻게 할까 고민해보니깐
그리디하게 풀면 될꺼 같아서 이렇게 접근했고 접근과정은 맞긴 했다.
조건 1.
1 ~ n 번째까지 가면서
1번째를 기준으로 잡고 그것의 오른쪽에 있는 수들중 제일 큰 수
2번째를 기준으로 잡고 그것의 오른쪽에 있는 수들중 제일 큰 수
......
이렇게 나갔다. 그리고 수가 좀 적은거 같으니깐 만약 제일 큰수가 여러개가 있다면
ex) 3 2 7 7 7 이 있으면
3 을 기준으로 잡고 max_num을 구하면 7인데 7이 3개가 있으니깐
7 2 3 7 7 (1번째와 3번쨰 swap)
7 2 7 3 7 (1번째와 4번째 swap)
7 2 7 7 3 (1번째와 5번째 swap)
이렇게 3개를 잡아 주고
2번쨰를 기준으로 잡고 그것의 오른쪽에 있는 수들중 제일 큰 수
ex) 7 2 3 7 7 이 있으면
7 7 3 2 7 (2번째와 4번쨰 swap)
7 7 3 7 2 (2번째와 5번쨰 swap)
이렇게 2개를 잡아 주고
이렇게 5번째를 오면 멈춘다.
조건 2.
만약 n번째를 오는중에 (남은 교환 횟수%2) == 0이라면 최대 정답값을 비교해준다.
왜냐하면 남은 교환 횟수가 짝수번이 남았다면 어떻게 교환을 하던 그 수를 만들 수 있기 때문이다.
ex) 7 2 3 7 7 에 남은 swap 횟수가 2번 남았다라는것은 2번의 swap으로 7 2 3 7 7을 무조건 만들 수 있기 때문이다.
생각해보면 당연하다.
그리고 남은 교환횟수가 0이라면 더이상 swap 못하니간 return을 해준다.
조건 3.
만약 n번째 자리까지 다왔는데 (남은 교환 횟수%2) == 1이라면
즉, 그리디하게 최대로 다 만들었는데 남은 교환 횟수가 홀수이면 맨 끝 2자리를 swap 한다.
ex) 4321 1 을 생각해보자.
이미 이 수는 최대지만 무조건 1번은 swap 해야 한다.
그러면 그나마 제일 손해가 적게 맨 끝 2자리를 swap 해야 한다.
그래서 만들었다.
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
|
import java.util.*;
import java.io.*;
import java.math.*;
public class Solution {
static int max;
static int len;
static char[] strs;
static void swap(int a, int b) {
char tmp = strs[a];
strs[a] = strs[b];
strs[b] = tmp;
}
static void go(int change_pos, int cnt) {
if(cnt%2 == 0)
max = Math.max(max, Integer.parseInt(new String(strs)));
if(cnt == 0) {
return;
}
if(change_pos == len-1) {
if(cnt%2 == 1) {
swap(len-2, len-1);
max = Math.max(max, Integer.parseInt(new String(strs)));
swap(len-2, len-1);
}
return;
}
int max_num = strs[change_pos] - '0';
for(int i = change_pos+1 ; i < len ; i++)
max_num = Math.max(max_num, strs[i] -'0');
if(max_num == strs[change_pos] - '0')
go(change_pos+1, cnt);
else {
for(int i = change_pos+1 ; i < len ; i++) {
if(max_num == strs[i] - '0') {
swap(i, change_pos);
go(change_pos+1 , cnt-1);
swap(i, change_pos);
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());
for(int z = 1 ; z <= tc ; z++) {
StringTokenizer st = new StringTokenizer(br.readLine());
String str = st.nextToken();
int change = Integer.parseInt(st.nextToken());
strs = str.toCharArray();
len = str.length();
//String swappedString = new String(c);
max = 0;
go(0, change);
System.out.println("#"+z+" "+max);
}
}
}
|
cs |
하지만 틀렸다.
않이 왜??????????????????
36~48번째줄을 잘못 만들었다.
반례는 77732 1 이였다.
기존 생각으로 짜면
첫번째 자리를 기준으로 swap 기준을 잡아보자.
수정 전에는 7보다 큰 수가 없으니깐 그냥 첫번째 자리는 swap없이 넘어갈 것이고
2번째도 3번째 4번째 5번째 다 없으니깐
5번째까지 swap 횟수를 소비하지 않을 것이고
조건 3에 의해서
77723이라는 답을 뱉을 것이다.
BUT... 77732 1 의 답은 77732이다. 오우 쒰!!!!!!!! (1,2번째 swap하면 된다.)
그래서 7보다 큰 수 -> 7보다 크거나 같은 수를 구하도록 바꿨다.
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
|
import java.util.*;
import java.io.*;
import java.math.*;
public class D210331_SWEA1244 {
static int max;
static int len;
static char[] strs;
static void swap(int a, int b) {
char tmp = strs[a];
strs[a] = strs[b];
strs[b] = tmp;
}
static void go(int change_pos, int cnt) {
if(cnt%2 == 0)
max = Math.max(max, Integer.parseInt(new String(strs)));
if(cnt == 0) {
return;
}
if(change_pos == len-1) {
if(cnt%2 == 1) {
swap(len-2, len-1);
max = Math.max(max, Integer.parseInt(new String(strs)));
swap(len-2, len-1);
}
return;
}
go(change_pos+1, cnt);
int max_num = strs[change_pos] - '0';
for(int i = change_pos+1 ; i < len ; i++) {
if(max_num <= strs[i] - '0') {
swap(i, change_pos);
go(change_pos+1 , cnt-1);
swap(i, change_pos);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());
for(int z = 1 ; z <= tc ; z++) {
StringTokenizer st = new StringTokenizer(br.readLine());
String str = st.nextToken();
int change = Integer.parseInt(st.nextToken());
strs = str.toCharArray();
len = str.length();
//String swappedString = new String(c);
max = 0;
go(0, change);
System.out.println("#"+z+" "+max);
}
}
}
|
cs |
그러니깐 정답을 뱉는다....
여윽시 뻑킹그리디다.
'뚝배기 터진 문제_SWEA' 카테고리의 다른 글
[SWEA] 1257 K번째 문자열 (0) | 2021.04.01 |
---|