[멀캠|Java] 12일차 수업
KB IT’s Your Life 4기 - Java 알고리즘 12일차
swea1233
package s1233;
import java.util.*;
import java.io.*;
public class Solution {
static class Node{
int value; // 노드 값
char opr; // 노드 연산자
int left,right; // 자식 노드 번호
// 생성자 오버라이딩 2개 (연산자 있는 경우 없는 경우)
public Node(int value, char opr, int left, int right) {
super();
// value와 opr은 서로 베타적이다. 공존하지 못함!
this.value = value;
this.opr = opr;
this.left = left;
this.right = right;
}
public Node(int value) {
super();
this.value = value;
}
}
static int N; // 노드 개수
static Node[] nodes;
private static int calc(Node node) {
// 연산자 추출
char opr = node.opr;
if(opr == '-') {
return calc(nodes[node.left]) - calc(nodes[node.right]);
}
else if(opr == '+') {
return calc(nodes[node.left]) + calc(nodes[node.right]);
}
else if(opr == '/') {
return calc(nodes[node.left]) / calc(nodes[node.right]);
}
else if(opr == '*') {
return calc(nodes[node.left]) * calc(nodes[node.right]);
}
else {
return node.value;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for(int i=1;i<=10;i++) {
int ans=0;
StringTokenizer st = new StringTokenizer(br.readLine());
int N=Integer.parseInt(st.nextToken());
nodes = new Node[N+1];
for(int j=1;j<=N;j++) {
// st에는 현재 [정점번호, 연산자, 왼쪽 자식 번호, 오른쪽 자식 번호] 혹은 [정점번호, 숫자]
st = new StringTokenizer(br.readLine());
// 입력 토큰 개수 판별
// 연산자인 경우
if(st.countTokens()==4) {
// 정점 번호는 제거하기
st.nextToken();
char c = st.nextToken().charAt(0);
int left_v = Integer.parseInt(st.nextToken());
int right_v = Integer.parseInt(st.nextToken());
nodes[j]= new Node(0,c,left_v,right_v);
}
// 값인 경우
else {
// 정점 번호는 제거하기
st.nextToken();
String tk = st.nextToken();
if(Character.isDigit(tk.charAt(0))) {
nodes[j]= new Node(Integer.parseInt(tk));
}else {
nodes[j]= new Node(0,tk.charAt(0),0,0);
}
}
}
//연산식체크
ans = 1;
for (int j = 1; j <= N; j++) {
Node nd = nodes[j];
if(nd.opr == '\u0000') {//숫자노드이면
if(nd.left != 0 || nd.right != 0) {
ans = 0;
break;
}
}else {//연산자노드
if(nd.left == 0||nd.right == 0) {//
ans = 0;
break;
}
}
}
System.out.println("#"+i+" "+ans);
}
}
}
그리디 알고리즘
- 동전 개수의 최솟값 구하기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 동전개수 {
static int N; // 동전 수
static int total; // 목표 금액
static int[] array; // 동전의 종류
static int count; // 사용할 동전의 최솟값
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());
total = Integer.parseInt(st.nextToken());
array = new int[N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
array[i] = Integer.parseInt(st.nextToken());
}
for (int i = N - 1; i >= 0; i--) {
if (array[i] <= total) {
count += total / array[i];
total %= array[i];
}
}
System.out.println(count);
}
}
Anomymous Class
package 리뷰;
public class AnonymousExam {
public static void main(String[] args) {
// 일회용 임시 자식 클래스를 만드는 법
A a = new A() {
int j = 100;
public void p() { // 이게 없으면, a.p()는 "A"가 출력된다.
System.out.println("B" + j); // anonymous class의 경우, j는 간접적으로만 호출 가능
}
}; // 중괄호는 선언부의 역할이다. A를 상속한 이름 없는 클래스
a.p();
// a.j; //이렇게는 부를 수 없음. 간접적으로만 호출이 가능함.
System.out.println(a.getClass().getName()); // 리뷰.AnonymousExam$1 > 클래스 이름을 추출하는 함수
MySwim mySwim = new MySwim() {
@Override
public void swimming() {
System.out.println("자유형 수영");
}
}; // MySwim은 인터페이스고 인터페이스는 new를 못한다. 인터페이스를 구현한 클래스를 선언하면, 오버라이딩이 꼭 필요.
mySwim.swimming(); //자유형 수영
System.out.println(mySwim.getClass().getName()); //리뷰.AnonymousExam$2 > anomy형태로 만들면 이름을 따로 만들 필요가 없어서 좋다. $1, $2 저절로 지어줌.
}
}
class A {
public void p() {
System.out.println("A");
}
}
interface MySwim {
void swimming();
}
class MySwimImpl implements MySwim {
@Override
public void swimming() {
}
}
b1931
package b1931;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int N; // 회의의 수
static int[][] array; // 회의의 시작시간과 끝나는 시간
static int end; // 끝나는 시간
static int count; // 배정 회의실 수
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());
array = new int[N][2];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
array[i][0] = Integer.parseInt(st.nextToken()); // 회의 시작하는 시간
array[i][1] = Integer.parseInt(st.nextToken()); // 회의 끝나는 시간
}
Arrays.sort(array, (o1, o2) -> o1[1] == o2[1] ? o1[0] - o2[0] : o1[1] - o2[1]);// 정렬함.
for (int i = 0; i < N; i++) {
if (end <= array[i][0]) {
end = array[i][1];
count++;
}
}
System.out.println(count);
}
}
분할정복 알고리즘
- 문제를 분할하여 작은 것부터 해결하여 결과적으로 전체적인 해결책을 얻는다.
- 코드가 직관적이고 병렬적으로 문제를 해결할 수 있다.
-
- 병합 정렬
- 하나의 리스트를 두 개의 균등한 크기로 분할하고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법이다.
-
- 퀵 정렬
- 기준 값을 두고 배열을 분할하여 각 부분 배열에 퀵 정렬을 순환적으로 적용하는 방식이다.
-
- 이진 탐색
- 정렬된 데이터를 탐색하는 것이다. (전제조건: 정렬)
백트래킹
-
미로의 탐색처럼 하나의 갈래길을 선택해서 따라가다 막히면 다음 갈래 길을 선택해서 따라가고 다시 벽이 나오면 갈래길까지 되돌아와서 다른 갈래 길을 선택해서 출구를 찾는 방법
-
swea 2806