• 코드

실패 코드 1 : String으로 특정 순서에 있는 문자를 가져오는 charAt를 통해 가져왔다. 결과는 메모리초과

               이유는 String 클래스 문자열의 최대 가능 길이는 2,147,483,647이기 때문에 뜬 것 같다.

 

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());
		
        int N = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        
        String number = "";
        int a = 0;
        for(int i=1;i<=N;i++) {
        	number+=i;
        	a += Math.log10(i)+1;
        	if(a>=k)
        		break;
        }
        
        if (a>k)
     	    System.out.println(number.charAt(k-1));
        else
    	    System.out.println("-1");
	}
}

 

실패 코드 2 : String 대신에 ArrayList로 해보았다. 결과는 메모리초과

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
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());
        
        ArrayList<String> list = new ArrayList<>();
        
        int a=0;
        boolean check = false;
        
        for(int i=1;i<=N;i++) {
        	a+=Math.log10(i)+1;
        	list.add(Integer.toString(i));
        	if(a>=k) {
        		check = true;
        		a = k-(a-(int)Math.log10(i)-1)-1;
        		break;
        	}
        }
        
        if(check)
        	System.out.println(list.get(list.size()-1).charAt(a));
        else
        	System.out.println("-1");
	}
}

 

실패 코드 3 : 해당 숫자만 String형태로 가져와서 원하는 숫자 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());
		
        int N = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
                
        int a=0;
        boolean check = false;
        String temp="";
        
        for(int i=1;i<=N;i++) {
        	a+=Math.log10(i)+1;
        	if(a>=k) {
        		check = true;
        		a = k-(a-(int)Math.log10(i)-1)-1;
        		temp = Integer.toString(i);
        		break;
        	}
        }
        
        if(check)
        	System.out.println(temp.charAt(a));
        else
        	System.out.println("-1");
	}
}

 

 

성공 코드 : 첫번째부터 마지막 수까지 계속하면 메모리초과, 런타임이 뜬다.

               수를 줄이기 위해서 첫번째 while 문에서 9,99,999안에 k가 있는지 판단하면서 length와 처음 입력한

               k의 자리 수 보다 적은 9*11111..꼴의 수를 가져온다.

               while 문을 빠져나온 뒤 k의 자리수 보다 적은 9*111...꼴의 수에 +1을 해줘서 자리 수를 맞춰주고,

               (k-1)/length를 더해줘서 원하는 정확한 int형의 값을 가져온다.

               만약 가지고 온 수가 N보다 높으면 입력한 수보다 높은 수를 출력하기 바랬기 때문에 -1출력

               N보다 작다면 (k-1)%length를 통해 원하는 수의 index값을 가져와서 출력해준다.

               어렵다..

 

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());
		
        int N = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        
		long finalNumber = 0;
		long length = 1;
		long numberOfDigits = 9;

		while (k > length * numberOfDigits) {
			k -= (length * numberOfDigits);
			finalNumber += numberOfDigits;
			
			length++;
			numberOfDigits *=10;
		}
				
		finalNumber = (finalNumber+1)+ (k-1)/length;
		if(finalNumber > N) {
			System.out.println(-1);
		}else {
			int index = (int) ((k-1)%length);
			System.out.println(String.valueOf(finalNumber).charAt(index));
		}
		
        
	}
}

 


 

  • 코드

1. 처음 if(arr[1][i]==1) 조건문에서 상근이의 친구를 찾는다.

2. 친구를 찾은 다음 상근이의 친구를 찾기위해서 if 문안에서 for문을 이용해서 찾는다.

결과는 맞았습니다!!

 

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));
		
        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());
        int [][]friend = new int[N+1][N+1];
		boolean []check = new boolean[N+1];
		int count = 0;

		for(int i=0; i<M; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			friend[a][b] = friend[b][a] = 1;	
		}

		for(int i=2; i<=N; i++) {
			if(friend[1][i] == 1) {	 
				if(!check[i]) {		 
					count ++;		 
					check[i] = true; 
				}

				
				for(int j=2; j<=N; j++) {
					if(friend[i][j] == 1 && !check[j]) {
						count ++;			
						check[j] = true;	
					}
				}
			}
		}

		System.out.println(count);
	}
}

 


 

  •  코드

초기 코드 1 : 각 숫자의 자리수를 Math.log10(i)+1를 통해 구한다. 결과는 시간초과

 

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));
        int N = Integer.parseInt(br.readLine());
        int count = 0;
        
        for(int i=1;i<=N;i++) 
        	count += Math.log10(i)+1;
        
        System.out.println(count);  
	}
}

 

 

초기 코드 2 :  String으로 반복문이 돌때마다 +i를 해준 뒤 string의 길이를 length()로 출력해보았다.

                  결과는 메모리초과

 

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));
        int N = Integer.parseInt(br.readLine());
        String count = "";
        
        for(int i=1;i<=N;i++) 
        	count += i;
        
        System.out.println(count.length());  
	}
}

 

  • 맞은 코드

일단 i의 수 120을 입력했다는 가정으로 보면

1의 자리이상 120개 + 2의 자리이상 120-9(1의 자리)개 + 3의 자리이상 120-9-90(2의 자리)개로 더 해주는 방식으로 풀었다.

결과는 맞았습니다!!

 

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));
        int N = Integer.parseInt(br.readLine());
        int count = 0;
        
        for(int i=1;i<=N;i*=10) 
        	count += N - (i-1);
        
        System.out.println(count);  
	}
}

 

 

- 코드

   - 많은 경우의 수를 고려했을 때 해결책은 평론가 수 - (소시지 수와 평론가 수의 최대공약수)로 나왔다. 

   - 최대공약수를 구하는 것을 재귀로 하려고하다가 재귀로하면 시간이 오래 걸린다는 말을 들어서 반복문으로 해결했다.

 

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());
        
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
		
    	int cutting = 0;

    	while (true) {
    		n = n % m;
    		
    		if (n == 0)
    			break;
    		if (m%n == 0)
    		{
    			cutting += (m / n - 1)*n;
    			break;
    		}
    		else {
    			cutting += (m / n)*n;
    			m = m % n;
    		}
    	}
    	
    	System.out.println(cutting);
	}
}

 

- 코드

   - 소수를 구하는 알고리즘인 제곱근을 사용하여서 시간을 줄였다.

 

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

public class Algorithm {
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        int n = Integer.parseInt(br.readLine());
                
        while(n!=0) {
			int count = 0;			
			
			for(int i = n + 1; i <= n * 2; i++) {
				boolean flag = false;
				for(int j = 2; j < (int)Math.sqrt(i) + 1; j++) {
					if(i % j == 0) {
						flag = true;
						break;
					}
				}
				if(!flag) count++;
			}
			
			System.out.println(count);
			n = Integer.parseInt(br.readLine());
		}
		
	}
}

 

- 코드

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

  - 문제는? 

 

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])));
		
	}
}

+ Recent posts