• 코드

실패 코드 : 기존 LCS 방식으로 해보았다. 결과는 메모리 초과, int[]를 stringbuilder로도 해봤지만 메모리 초과

                메모리 초과의 이유는 (10만x10만xsizeof(int))이기 때문이였다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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));

		long input = Long.parseLong(br.readLine());
		
		int[] firstArray = new int[(int) input];
		int[] secondArray = new int[(int) input];
		
		StringTokenizer string = new StringTokenizer(br.readLine());
		for(long i=0;i<input;i++) {
			firstArray[(int) i] = Integer.parseInt(string.nextToken());
		}
		string = new StringTokenizer(br.readLine());
		for(long i=0;i<input;i++) {
			secondArray[(int) i] = Integer.parseInt(string.nextToken());
		}
		

		int[][] dp = new int[(int) (input + 1)][(int) (input + 1)];

		for (int i = 1; i <= firstArray.length; i++) {
			for (int j = 1; j <= secondArray.length; j++) {
					if (firstArray[i-1] == secondArray[j - 1]) {
						dp[i][j] = dp[i - 1][j - 1] + 1;
					} else {
						dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
					}
				
			}
		}
		
		System.out.println(dp[firstArray.length][secondArray.length]);
	}
}

 

 

성공 코드 : 첫번째 배열을 LIS배열에 순서대로 넣고, 두번째 배열을 LIS 알고리즘에 따라서 풀었다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
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));
        
        int input = Integer.parseInt(br.readLine());
        int[] LIS = new int[input + 1];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= input; i++)
            LIS[Integer.parseInt(st.nextToken())] = i;
        
        int[] arrays = new int[input];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < input; i++)
            arrays[i] = LIS[Integer.parseInt(st.nextToken())];
        
        int j = 0;
        LIS[j++] = arrays[0];
        for (int i = 1; i < input; i++) {
            int index = Arrays.binarySearch(LIS, 0, j, arrays[i]);
            if (index == -(j + 1))
                LIS[j++] = arrays[i];
            else
                LIS[-(index + 1)] = arrays[i];
        }
        System.out.print(j);
	}
}

 


 

  • 코드

정답 코드 : LCS algorithm의 방식을 3차원으로 가져와서 풀었다. (https://www.youtube.com/watch?v=EAXDUxVYquY - 알고리즘 설명 링크)

 

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

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String firstInput = br.readLine();
		String secondInput = br.readLine();
		String thirdInput = br.readLine();

		int[][][] dp = new int[firstInput.length() + 1][secondInput.length() + 1][thirdInput.length() + 1];

		for (int i = 1; i <= firstInput.length(); i++) {
			for (int j = 1; j <= secondInput.length(); j++) {
				for (int z = 1; z <= thirdInput.length(); z++) {
					if (firstInput.charAt(i - 1) == secondInput.charAt(j - 1) 
							&& secondInput.charAt(j - 1) == thirdInput.charAt(z-1)) {
						dp[i][j][z] = dp[i - 1][j - 1][z - 1] + 1;
					} else {
						dp[i][j][z] = Math.max(dp[i][j][z-1] ,Math.max(dp[i][j - 1][z], dp[i - 1][j][z]));
					}
				}
			}
		}
		
		System.out.println(dp[firstInput.length()][secondInput.length()][thirdInput.length()]);
	}
}

 


 

  • 코드

실패 코드 : 처음 코드는 아니고 많이 바꾼 코드인데, 젤 긴 건물의 index를 찾은 뒤, 그 건물부터 보이는 건물의 개수를 왼쪽, 오른쪽을 체크한 뒤 건물의 수를 오른쪽 index - 왼쪽 index로 출력했다. 이게 아닌가 보다... 문제 이해가 안된건가...

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
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));
		
		int number = Integer.parseInt(br.readLine());
		long [] array = new long[number];
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		for(int i=0;i<array.length;i++) 
			array[i] = Long.parseLong(st.nextToken());
		
		int maxValueIndex = 0;
		long saveValue=0;
		for(int i=0;i<array.length;i++) {
			if(saveValue<array[i]) {
				maxValueIndex=i;
				saveValue=array[i];
			}				
		}
		
		int max = 0;
		for(int i=1;i<maxValueIndex;i++) {
			if(array[max]<=array[i])
				max=i;
		}
		
		int max1 = maxValueIndex+1;
		for(int i=maxValueIndex+2;i<array.length;i++) {
			if(array[max1]<array[i])
				max1=i;
		}
		
		System.out.println(max1-max);
    }
}

 

다른 사람 설명 봤는데 CCW 알고리즘을 설명한다.. 다음에 공부해서 풀어봐야겠다..

 

 


 

  • 코드

정답 코드 : 소수의 값들을 boolean배열에 false로 해놓고(에라토스테네스의 체) 해당 인덱스를 ArrayList에 넣어둔다. HashSet이 아닌 ArrayList에 넣는 이유는 넣는 순서를 유지시키기 위함. 그리고 입력 값의 수를 세는 것은 주석으로 설명해 놨다.

에라토스테네스의 체, 투 포인터 방식 사용

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
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));
		
		long N = Long.parseLong(br.readLine());
        ArrayList<Integer> primeNumber = new ArrayList<>();
		
        boolean[] prime = new boolean[(int) (N+1)];
        prime[0] = prime[1] = true;
        
        for(int i=2; i*i<=N; i++){
            if(!prime[i]) {
            	for(int j=i*i; j<=N; j+=i) 
            		prime[j]=true;      
            }
        }            
        for(int i=2; i<=N;i++){
        	if(!prime[i]) primeNumber.add(i);     
        }
        
        int start=0, end=0, sum=0, count=0;
        while(true) {
        	if(sum==N) {		
        		count++;
        		sum-=primeNumber.get(start++);
        	}
        	else if(sum>N) {	//sum이 N보다 커지면 작은 소수의 값부터 점점 빼줌
        		sum-=primeNumber.get(start++);
        	}
        	else if(end == primeNumber.size()) { //sum이 N보다 작은데 end의 위치가 primeNumber.size랑 같으면 더이상 더해줄게 없기때문에 break;
        		break;
        	}
        	else {		//sum이 N보다 작으면 소수의 작은 값부터 큰값으로 점점 더해줌
        		sum+=primeNumber.get(end++);
        	}
        }
        
        System.out.println(count);
    }
}

 


 

  • 코드

정답 코드 : 문제를 읽다보니까, 정규식이 생각나서 정규식으로 한번 풀어보았다.

 

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

public class Main {
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub        
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		String sound = br.readLine();
		String check = "(100+1+|01)+";
		
		if(sound.matches(check))
			System.out.println("SUBMARINE");
		else
		    System.out.println("NOISE");
		
	}
}

 


 

  • 코드

정답 코드 : boolean 배열에 초기 false로 채워두고 지나간 값은 true로 변환해준다. true일시 건너띄고 false일 시 true로 바꿔주면서 count++해준다. count가 K랑 같아질 시 출력하고 종료.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
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));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int N = Integer.parseInt(st.nextToken());
		int K = Integer.parseInt(st.nextToken());
		
		boolean[] check = new boolean[N+1];

	    int count = 0;

	    Arrays.fill(check, Boolean.FALSE);

	    for(int i = 2; i <= N; i++) {
	        for(int j = i; j <= N; j += i) {
	            if(check[j])
	                continue;
	            check[j] = true;
	            count ++;
	            if(count == K) {
	                System.out.println(j);
	                System.exit(0);
	            }
	        }
	    }
	  }
}

 


 

  • 코드

실패 코드 : 일단 원하는대로 값은 나오는데 시간 초과가 뜬다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
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));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		long min = Long.parseLong(st.nextToken());
		long max = Long.parseLong(st.nextToken());
		
		int count = (int) (max-min+1);
		for(int j=(int) min;j<=max;j++) {
			for(int i=2;i*i<=max;i++) {
				if(j%(i*i)==0) {
					count--;
					break;
				}
			}
		}
		
		System.out.println(count);
				
    }
}

 

 

정답 코드  : 에라토스테네스의 체 방식과 비슷한 방식으로 풀어 보았다.

                i가 2일때부터 i*i값을 가져와서 min값에서 가장 가까운 i*i로 떨어지는 값을 찾는다. 찾는 방법이 힘들었는데 찾은 식은 min +(index - (min%index))%index이다. 여기서 index는 i*i 값이다. i*i로 나누어 떨이지는 값들을 min부터 max값까지 모두 체크하고 i+1하고 해당 작업을 반복해주는 방식으로 하였다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		long min = Long.parseLong(st.nextToken());
		long max = Long.parseLong(st.nextToken());
		
		int range = (int) (max-min+1);
		
		boolean [] check = new boolean[range];
		
		for(long i=2;i*i<=max;i++) {
			long index = i*i;
			long startNumber = min +(index - (min%index))%index;
			
			for(long j = startNumber; j<=max;j+=index) {
				check[(int) (j-min)] = true;
			}
		}
		
        int count = 0;
        for(int i = 0; i < range; i++){
            if(!check[i])
                count++;
        }
        System.out.println(count);
				
    }
}

 

 

 


 

  • 문제 풀기 전 알아야 할 것

정답 코드 : 피보나치 문제풀 때 재귀로 풀었던 것이 생각이 나서 재귀로 풀려니까 시간이 너무 많이 걸릴 것 같아서 배열로 하자니 수가 너무 커서 주기가 있을 것 같아서, 피보나치 주기를 쳐보니 해결책이 나왔다.

 

피보나치 수를 K로 나눈 나머지는 항상 주기를 가지게 됩니다. 이를 피사노 주기(Pisano Period)

 

주기의 길이가 P 이면, N번째 피보나치 수를 M으로 나눈 나머지는 N%P번째 피보나치 수를 M을 나눈 나머지와 같습니다. M = 10^k 일 때, k > 2 라면, 주기는 항상 15 × 10^(k-1) 입니다. 이 사실을 모른다고 해도, 주기를 구하는 코드를 이용해서 문제를 풀 수 있습니다. 이 문제에서 M = 10^6 이기 때문에, 주기는 15 × 10^5 = 1500000가 됩니다.

 

  • 코드

정답 코드 : 위의 내용을 토대로 코드를 작성하였다. 주기를 찾아서 "입력한 수의 % 1500000 크기"의 배열을 만들어서 피보나치 수열을 정렬하였고, "입력한 수의 % 1500000 크기"번째의 값을 출력했다.

 

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

public class Main {
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub        
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
		long number = Long.parseLong(br.readLine());
		int cycle = (int)(number % 1500000);
		
		long[] fibonacciArray = new long[cycle+1];
		
		fibonacciArray[0]=0;
		fibonacciArray[1]=1;		
		
		for (int i = 2; i <= cycle; i++) 
			fibonacciArray[i] = (fibonacciArray[i-1] + fibonacciArray[i-2])%(long)Math.pow(10,6);
		
		System.out.println(fibonacciArray[cycle]);		
    }
}

 

다른 사람의 코드 : 나보다 속도가 빠르다. 사용한 방법은 행렬을 이용한 방법이다. 공부해두면 좋을 것 같다.

 

import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static BigInteger N;
    static long[][] matrix = new long[2][2];
    static int mod = 1000000;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = new BigInteger(br.readLine());
        if (N.equals(new BigInteger("1"))) {
            System.out.println(1);
        } else {
            matrix[0][0] = 1;
            matrix[1][0] = 1;
            matrix[0][1] = 1;
            matrix[1][1] = 0; // 피보나치 수를 구하는 하나의 방식, 나머지는 DP와 일반항
            matrix = getFibo(N.subtract(new BigInteger("1")));
            System.out.println(matrix[0][0]);
        }
    }

    private static long[][] getFibo(BigInteger N) {
        if (N.equals(new BigInteger("1")))
            return matrix;
        long[][] P = getFibo(N.divide(new BigInteger("2")));
        if (N.mod(new BigInteger("2")).equals(new BigInteger("0"))) {
            return MultiMatrix(P, P);
        } else {
            return MultiMatrix(MultiMatrix(P, P), matrix); // 아마 오버플로우는 없을 것이다
        }

    }

    private static long[][] MultiMatrix(long[][] A, long[][] B) {
        long[][] M = new long[2][2];
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 2; k++) {
                    M[i][j] += A[i][k] * B[k][j];
                    M[i][j] %= mod; // 추측: mod 연산은 이것만으로 충분할 것
                }
            }
        }
        return M;
    }

    // private static void Print(long[][] arr) {
    //     System.out.println();
    //     for (int i = 0; i < 2; i++) {
    //         for (int j = 0; j < 2; j++) {
    //             System.out.print(arr[i][j] + " ");
    //         }
    //         System.out.println();
    //     }
    // }
}

+ Recent posts