- 코드

  - 초기 코드인데, 시간초과가 뜬다.

  - 문제는? 

 

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, m;
	static String temp;
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				
		temp = br.readLine();
		StringTokenizer st = new StringTokenizer(temp);
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		
		String[] a = new String[n+m];

		for(int i=0;i<n+m;i++) {
			a[i] = br.readLine();
		}

		for(int i=0;i<m;i++) {
			for(int j=0;j<n;j++) {
				if(a[i+n].equals(a[j])) {
					System.out.println(a[i+n]);
					break;
				}
			}
		}
		
	}
}

 

- 마지막 코드

   - String배열 대신 ArrayList와 HashSet을 사용하니 속도가 개선되었다. 출력은 BufferedWriter를 사용했다. 이유는 아래에 정리

 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        
        HashSet<String> a = new HashSet<>();
        ArrayList<String> list = new ArrayList<>();
        
        for(int i = 0; i < n; i++){
            a.add(br.readLine());
        }

	for(int i=0;i<m;i++) {
		String temp = br.readLine();
		if(a.contains(temp))
			list.add(temp);
        }
		
	Collections.sort(list);	
	bw.write(list.size() + "\n");
	for(String temp : list)
		bw.write(temp + "\n");

        bw.flush();
        br.close();
        bw.close();
		
	}
}

 

 

- 정리 

   - 아무리 생각해도 속도를 개선할 방법이 떠오르지 않아서 다른 사람의 코드를 보았다. (다른 점은 HashSet, ArrayList와 BufferedWriter를 사용했다는 것!!)

   - BufferedReader, BufferedWriter, StringTokenizer를 사용하는 이유는 따로 블로그에 정리하였습니다.

   - HashSet과 ArrayList를 쓰면 빨라지는 이유는 HashSet이다. HashSet의 특징은 중복된 값을 허용 X, 순서를 보장하지 않는다. List는 본질적으로 순서를 관리해야 하기 때문에 내부적으로 순서 정보를 알 수 있도록 구현해야 한다. ArrayList도 List 인터페이스를 구현한 클래스이므로, 순서 정보를 관리해야하며, 이를 위해 내부적으로 배열(Array)을 사용하여 구현되어 있다. 그렇기 때문에 상대적으로 시간이 오래걸린다.

 

 반면에, HashSet은 순서를 보장할 필요가 없다. 그러므로 Set에 저장된 무언가를 찾을 때는, 순서와 상관없이 그냥 찾으면 되는 것이므로, 찾는 방법이 List에 비해 자유로울 수 있다. 이때 찾는 속도를 극대화 하기위해 Set을 구현할 때 Hash를 사용한 것이 HashSet이다. Hash로 검색하면 검색 시간이 데이터 크기에 상관없이 일정하게 매우 짧다!!라고 이해하면 될 것 같다.

 

결론 : List를 쓰나 Set을 쓰나 동작에 차이가 없다면 HashSet을 써라!!!

 

- 코드

  - 처음으로 구현문제를 풀어서 브론즈부터 풀어봤다.

 

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;
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int count = 0;
		n = Integer.parseInt(br.readLine());
		
		while(true) {
			if (n==0)
				break;
			
			if (n%5==0) 
				n-=5;
			else if (n%3==0)
				n-=3;
			else if (n>5)
				n-=5;
			else if (n>3)
				n-=3;
			else
				break;
			count++;
		}
		
		if(n!=0)
			System.out.println("-1");
		else
			System.out.println(count);
		
		
	}
}

 

- 코드

  - 점화식은 R,G,B 입력을 받을때 R이면 이전 값의 G,B를 더해준 값을 현재 R의 인덱스에 넣어주는 식으로 하였다.

 

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 String temp;
	static int[][] dp;
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		n = Integer.parseInt(br.readLine());
		
		dp = new int[n][3];
		
		temp = br.readLine();
		StringTokenizer st = new StringTokenizer(temp);
		dp[0][0] = Integer.parseInt(st.nextToken());
		dp[0][1] = Integer.parseInt(st.nextToken());
		dp[0][2] = Integer.parseInt(st.nextToken());
		
		for (int i=1;i<n;i++) {
			temp = br.readLine();
			st = new StringTokenizer(temp);
			dp[i][0] = Integer.parseInt(st.nextToken());
			dp[i][1] = Integer.parseInt(st.nextToken());
			dp[i][2] = Integer.parseInt(st.nextToken());
			
			dp[i][0] = Math.min(dp[i][0] + dp[i-1][1], dp[i][0] + dp[i-1][2]);
			dp[i][1] = Math.min(dp[i][1] + dp[i-1][0], dp[i][1] + dp[i-1][2]);
			dp[i][2] = Math.min(dp[i][2] + dp[i-1][0], dp[i][2] + dp[i-1][1]);
		}
		
		System.out.println(Math.min(dp[n-1][0], Math.min(dp[n-1][1],dp[n-1][2])));
		
	}
}

 

- 초기 코드

  - 기존 피보나치 코드를 활용해서 풀었지만, 시간 초과가 떴다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	
	static int N,num;	
	static int[] dp;
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		N = Integer.parseInt(br.readLine());
		
		for (int i = 0; i < N; i++) {
			dp = new int[2];
			num = Integer.parseInt(br.readLine());
			fibonacci(num);
			System.out.println(dp[0] + " " + dp[1]);
		}		
	}
	
	static void fibonacci (int n) {
		if (n==0) {
			dp[0] += 1;
		} else if (n==1) {
			dp[1] += 1;
		} else {
			fibonacci(n-1);
			fibonacci(n-2);
		}
	}
}

 

- 맞은 코드

  - 기존 피보나치 메소드를 사용하는 것이 아닌, 점화식을 통해서 풀었다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	
	static int T,N;	
	static int[][] dp;
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		T = Integer.parseInt(br.readLine());
		dp = new int[41][2];
		
		dp[0][0] = 1;
		dp[1][1] = 1;
		
		for (int i = 2; i <41 ; i ++) {
			dp[i][0] = dp[i-1][0] + dp[i-2][0];
			dp[i][1] = dp[i-1][1] + dp[i-2][1];
		}
		
		for (int i = 0; i < T; i++) {
			N = Integer.parseInt(br.readLine());
			System.out.println(dp[N][0] +" "+ dp[N][1]);
		}		
	}
}

 

 

- 코드 설명

 - 입력이 양수이며 11보다 작다고해서 하나하나 쓰다가 규칙을 찾게 되었다.

 - 규칙은 배열에 dp[0]=1, dp[1]=1, dp[2]=2를 넣은다음 dp[i] = dp[i-3] + dp[i-2] + dp[i-1]로 각 배열마다 값을 넣어주면 1,2,3의 합으로 표현할 수 있는 수가 나오는 것을 발견하였다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	
	static int N,num;
	static int[] dp;

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		N = Integer.parseInt(br.readLine());
		
		dp = new int[11];
		
		dp[0] = 1;
		dp[1] = 1;
		dp[2] = 2;
		
		for (int i = 3; i<11;i++) {
			dp[i] = dp[i-3] + dp[i-2] + dp[i-1];
		}
		
		for (int i = 0; i < N; i++) {
			num = Integer.parseInt(br.readLine());
			System.out.println(dp[num]);
		}
		
	}
}

 

 

 

초기 코드

 - 5개씩 값을 가져와서 문제대로 연속 3개가 나오지 않도록 더해지는 최대 수의 앞쪽 인덱스 3개의 값들만 더해서 total에 더해준다. 이 작업의 for문은 index를 3개씩 증가시킴.

 - 여기서 문제는 가져온 3개의 인덱스가 다음 for문에서 연속 3개가 나오지 않게해야된다. (맨뒤의 인덱스 O X O는 flag를 통해서 막았는데 X O O이렇게 더해준경우를 생각하지 못했다.)

 

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
    	Scanner scanner = new Scanner(System.in);
        
    	int X = scanner.nextInt(); //정수 값 받아옴
    	int[] array = new int[X+4];		//배열 선언
    	
    	for(int i = 0; i<X;i++) {
    		array[i] = scanner.nextInt();
    	}
    	
    	int total = 0;
    	boolean flag = true;
    	for(int i = 0; i<X;i=i+3) {
    		int total1 = 0;
    		int max = 0;
    		
    		if (total1 < array[i]+array[i+2]+array[i+4]) {
    			total1 = array[i]+array[i+2]+array[i+4];
    			max = array[i]+array[i+2];
    			flag = false;
    		}
    		
    		if (flag && total1 < array[i] + array[i+1] + array[i+3] + array[i+4]) {
    			total1 = array[i] + array[i+1] + array[i+3] + array[i+4];
    			max = array[i] + array[i+1];
    			flag = true;
    		}
    		if (total1 < array[i] + array[i+2] + array[i+3]) {
    			total1 = array[i] + array[i+2] + array[i+3];
    			max = array[i] + array[i+2];
    			flag = false;
    		}
    		if (total1 < array[i+1] + array[i+3] + array[i+4]) {
    			total1 = array[i+1] + array[i+3] + array[i+4];
    			max = array[i+1];
    			flag = true;
    		}
    		if (total1 < array[i+1] + array[i+2] + array[i+4]) {
    			total1 = array[i+1] + array[i+2] + array[i+4];
    			max = array[i+1] + array[i+2];
    			flag = false;
    		}
    		total += max;
    	}
    	
    	System.out.println(total);
	}
}

 

 

중간 코드

- 위의 X O O를 고른 경우까지도 막았다. 제출해봤는데 틀렸다고한다. 반례 모두 다 잘 되는데 어디가 틀렸을까... 코드가 더럽다.. 맞춘다음에 바꿔보고싶다.. 어디가 틀린걸까..?

 

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
    	Scanner scanner = new Scanner(System.in);
        
    	int X = scanner.nextInt(); //정수 값 받아옴
    	int[] array = new int[X+4];		//배열 선언
    	
    	for(int i = 0; i<X;i++) {
    		array[i] = scanner.nextInt();
    	}
    	
    	int total = 0;
    	boolean flag = true;
    	boolean flag2 = true;

    	for(int i = 0; i<X;i=i+3) {
    		int total1 = 0;
    		int max = 0;
    		
    		if (flag2 && total1 < array[i]+array[i+2]+array[i+4]) {
    			total1 = array[i]+array[i+2]+array[i+4];
    			max = array[i]+array[i+2];
    		}
    		
    		if (flag2 && flag && total1 < array[i] + array[i+1] + array[i+3] + array[i+4]) {
    			total1 = array[i] + array[i+1] + array[i+3] + array[i+4];
    			max = array[i] + array[i+1];
    		}
    		if (flag2 && total1 < array[i] + array[i+2] + array[i+3]) {
    			total1 = array[i] + array[i+2] + array[i+3];
    			max = array[i] + array[i+2];
    		}
    		if (total1 < array[i+1] + array[i+3] + array[i+4]) {
    			total1 = array[i+1] + array[i+3] + array[i+4];
    			max = array[i+1];
    		}
    		if (total1 < array[i+1] + array[i+2] + array[i+4]) {
    			total1 = array[i+1] + array[i+2] + array[i+4];
    			max = array[i+1] + array[i+2];
    		}
    		
    		if (total1 == array[i]+array[i+2]+array[i+4]) {
    			flag = false;
    			flag2 = true;
    		}
    		
    		if (total1 == array[i] + array[i+1] + array[i+3] + array[i+4]) {
    			flag = true;
    			flag2 = true;
    		}
    		if (total1 == array[i] + array[i+2] + array[i+3]) {
    			flag = false;
    			flag2 = true;
    		}
    		if (total1 == array[i+1] + array[i+3] + array[i+4]) {
    			flag = true;
    			flag2 = true;
    		}
    		if (total1 == array[i+1] + array[i+2] + array[i+4]) {
    			flag = false;
    			flag2 = false;
    		}
    		
    		total += max;
    	}
    	
    	System.out.println(total);
	}
}

 

- DP 에 대해 배운 뒤 고친 코드

 - 맞았다고 잘 뜬다. arr 배열과 dp배열을 이용해 앞에서부터 차근차근 풀어나가는 dp 방식으로 풀었다.

 

import java.util.Scanner;

public class Algorithm {
    public static void main(String args[]) {
    	Scanner scanner = new Scanner(System.in);
        
    	int X = scanner.nextInt(); //정수 값 받아옴
    	int[] dp = new int[X+3];		//배열 선언
    	int[] arr = new int[X+3];
    	
    	for(int i = 3; i<X+3;i++) {
    		arr[i] = scanner.nextInt();
    	}

        for (int i = 3; i < X+3; i++) {
            dp[i] = Math.max(dp[i-3] + arr[i-1] + arr[i], dp[i-2] + arr[i]);
            dp[i] = Math.max(dp[i-1], dp[i]);
        }
    	
    	System.out.println(dp[X+2]);
	}
}

 

- 다른 사람들의 코드

  - 메모리, 시간 모두 1/2인 사람들이 있길래 어떻게 하는건가 보고 내꺼랑 비슷하게 바꿔봤는데 메모리랑 속도가 확실히 빠르게 된다 왜그렇지?? 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Algorithm {
	
	static int N;
	static int[] arr;
	static int[] dp;

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		N = Integer.parseInt(br.readLine());
		
		dp = new int[N+3];
		arr = new int[N+3];
		
		for (int i = 3; i < N+3; i++) {
			arr[i] = Integer.parseInt(br.readLine());
		}
		
        for (int i = 3; i < N+3; i++) {
            dp[i] = Math.max(dp[i-1], Math.max(dp[i-3] + arr[i-1] + arr[i], dp[i-2] + arr[i]));
        }
		
		System.out.println(dp[N+2]);
		
	}
}

+ Recent posts