정당성 분석이란 그리디 알고리즘을 사용했을 때, 최적의 해를 구할 수 있는지를 확인하는 것이다.
import java.util.Scanner;
// n 원을 거슬러줘야 하는 경우
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int count = 0;
int[] coinTypes = {500, 100, 50, 10};
for (int i = 0; i < 4; i++) {
count += n / coinTypes[i];
n %= coinTypes[i];
}
System.out.println(count);
}
}
실행 결과
1260
6
위와 같은경우는 정당성이 성립 한다.
왜냐면 하위 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문이다.
큰 단위가 항상 작은 단위의 배수가 아닌 경우에는 정당성이 성립하지 않는다.
이 때 거스름돈 시간 복잡도는 O(K)이다. K는 동전의 종류이다.
구현 유형 예시는 다음과 같다.
일반적으로 알고리즘 문제에서의 2차원 공간은 행렬(Matrix)의 의미로 사용된다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// N을 입력받기
int n = sc.nextInt();
sc.nextLine(); // 버퍼 비우기
String[] plans = sc.nextLine().split(" ");
int x = 1, y = 1;
// L, R, U, D에 따른 이동 방향
int[] dx = {0, 0, -1, 1};
int[] dy = {-1, 1, 0, 0};
char[] moveTypes = {'L', 'R', 'U', 'D'};
// 이동 계획을 하나씩 확인
for (int i = 0; i < plans.length; i++) {
char plan = plans[i].charAt(0);
// 이동 후 좌표 구하기
int nx = -1, ny = -1;
for (int j = 0; j < 4; j++) {
if (plan == moveTypes[j]) {
nx = x + dx[j];
ny = y + dy[j];
}
}
// 공간을 벗어나는 경우 무시
if (nx < 1 || ny < 1 || nx > n || ny > n) continue;
// 이동 수행
x = nx;
y = ny;
}
System.out.println(x + " " + y);
}
}
출력 결과
5
R R R U D D
3 4
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// H를 입력받기
int h = sc.nextInt();
int count = 0;
for (int i = 0; i <= h; i++) {
for (int j = 0; j < 60; j++) {
for (int k = 0; k < 60; k++) {
// 매 시각 안에 '3'이 포함되어 있다면 카운트 증가
if (String.valueOf(i).contains("3") || String.valueOf(j).contains("3") || String.valueOf(k).contains("3")) {
count++;
}
}
}
}
System.out.println(count);
}
}
출력 결과
5
11475
위 예제의 유형을 완전 탐색 문제라고 한다.
완전 탐색은 모든 경우의 수를 주저 없이 다 계산하는 해결 방법을 의미한다.
이처럼 완전 탐색은 문제를 해결할 수 있는 가장 무식한 방법이지만,
답을 찾을 수 있다는 점에서 가장 확실한 방법이다.
그러나 완전 탐색을 사용하면 시간 복잡도가 O(N^3)이 되어서 문제를 풀 수 없는 경우도 있다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 현재 나이트의 위치 입력받기
String inputData = sc.nextLine();
int row = inputData.charAt(1) - '0';
int column = inputData.charAt(0) - 'a' + 1;
// 나이트가 이동할 수 있는 8가지 방향 정의
int[] dx = {-2, -1, 1, 2, 2, 1, -1, -2};
int[] dy = {-1, -2, -2, -1, 1, 2, 2, 1};
// 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인
int result = 0;
for (int i = 0; i < 8; i++) {
// 이동하고자 하는 위치 확인
int nextRow = row + dx[i];
int nextColumn = column + dy[i];
// 해당 위치로 이동이 가능하다면 카운트 증가
if (nextRow >= 1 && nextRow <= 8 && nextColumn >= 1 && nextColumn <= 8) {
result += 1;
}
}
System.out.println(result);
}
}
출력 결과
a1
2
import java.util.Arrays;
public static String reString(String str){
String[] strArr = str.split("");
Arrays.sort(strArr);
StringBuilder result = new StringBuilder();
int sum = 0;
for(String s : strArr){
if(s.matches("[0-9]")){
sum += Integer.parseInt(s);
}else{
result.append(s);
}
}
return result.toString() + sum;
}
출력 결과
reString("K1KA5CB7")
-> "ABCKK13"