알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

https://www.acmicpc.net/problem/11720

 

11720번: 숫자의 합

첫째 줄에 숫자의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄에 숫자 N개가 공백없이 주어진다.

www.acmicpc.net


Think🤔

쉬운 문제 바로 코드 구현


Solution✍
package back23y02;

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

public class numberHan {

	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		int num = Integer.parseInt(bf.readLine());
		String str = bf.readLine();
		int answer = 0;
		
		for(int i=0; i<num; i++) {
			answer += str.charAt(i)-48;
		}
		System.out.println(answer);
	}

}

Review🤩

아스키 코드 -48을 빼서 answer에 각 자리수의 합을 넣어준다.

버퍼리더의 안쪽 부분이 잠시 생각이 안났었다~ 🤣


 

'Algorithm' 카테고리의 다른 글

[백준] 연속부분최대곱  (0) 2022.03.01
[백준] 설탕 배달  (0) 2022.02.28
[인프런] 아나그램(해쉬)  (0) 2022.02.27
[백준] 일곱 난쟁이  (0) 2022.02.27
[프로그래머스] [1차] 다트 게임  (0) 2022.02.26

아나그램이란? 두 문자열이 알파벳의 나열 순서는 다르지만 그 구성이 일치하면 두 단어를 아나 그램이라고함.

AbcdE EdcbA 이런식이면 나를 순서는 다르지만 개수가 일치하여 이것은 아나 그램이라 할 수 있다.

맞으면 Yes를 출력 아니면 No를 출력한다.

 

public class Main {
	public String solution(String s1, String s2) {
		String answer = "YES";
		HashMap<Character, Integer> map = new HashMap<>();
		for(char x : s1.toCharArray()) {
			map.put(x, map.getOrDefault(x, 0)+1);
		}
		for(char x : s2.toCharArray()) {
			if(!map.containsKey(x) || map.get(x) == 0) {
				return "NO";
			}
			map.put(x, map.get(x)-1);
		}
		
		return answer;
	}

	public static void main(String[] args){
		Main T = new Main();
		Scanner sc = new Scanner(System.in);
		String a = sc.next();
		String b = sc.next();
		System.out.print(T.solution(a,b));
	}

}

return "NO"; 를 안하고 answer에다가 대입하면 map.put -1 부분에서 없는 값에 -1하려고 해서 널포인트 익셉션이 뜰 수 있다.


	public int solution(String a, String b) {
		int answer = 0;
		HashMap<Character, Integer> am = new HashMap<>();
		HashMap<Character, Integer> bm = new HashMap<>();
		for(char x : b.toCharArray()) {
			bm.put(x, bm.getOrDefault(x,0)+1);
		}
		int L = b.length()-1;
		for(int i=0; i<L; i++) {
			am.put(a.charAt(i), am.getOrDefault(a.charAt(i),0)+1);
		}
		
		int lt = 0;
		
		for(int rt=L; rt<a.length(); rt++) {
			am.put(a.charAt(rt), am.getOrDefault(a.charAt(rt), 0)+1);
			if(am.equals(bm)) {
				answer++;
			}
			am.put(a.charAt(lt), am.get(a.charAt(lt))-1);
			if(am.get(a.charAt(lt))== 0) {
				am.remove(a.charAt(lt));
				lt++;
			}
		}
		
		return answer;
	}

	public static void main(String[] args){
		Main T = new Main();
		Scanner sc = new Scanner(System.in);
		String a = sc.next();
		String b = sc.next();
		System.out.print(T.solution(a,b));
	}

두 개의 값을 받아서 연속되는 문자를 포함하고 있는지 확인하는 알고리즘이다.

일단 포함인걸 확인하는 b를 반복문을 통해서 bm에 넣어준다.

 

그리고 L은 acd의 길이 이다

 

반복문을 이용해서 am에 있는 숫자를 acd인 bm만큼 넣어준다

 

그리고 왼쪽 lt를 0으로 하고

 

rt는 L부터 시작하고 a의 길이만큼 돌게 만들어준다.

 

만약에 3글자라면 일단 그 길이만큼 2개를 넣어주고, 그 다음 마지막 문자를 rt로 둬서 반복문을 돌려서 넣는 방법을 한다.

 

그 다음 -1한 값이 0이면 삭제해줘야 한다. remove로

'Algorithm' 카테고리의 다른 글

[백준] 설탕 배달  (0) 2022.02.28
[백준] 숫자의 합  (0) 2022.02.28
[백준] 일곱 난쟁이  (0) 2022.02.27
[프로그래머스] [1차] 다트 게임  (0) 2022.02.26
[프로그래머스] 두 정수 사이의 합  (0) 2022.02.24
알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

https://www.acmicpc.net/problem/2309

 

2309번: 일곱 난쟁이

아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.

www.acmicpc.net


Think🤔

내가 생각하는 방법

 

문제를 분석해보면, 일곱 난쟁이가 와야하는데 아홉 난쟁이가 와서 두명의 난쟁이는 제외 시키고 오름차순으로 출력해줘야 한다.

 

아홉 난쟁이에서 두명을 뺄때는 가장 큰 두명의 난쟁이를 제외시킨다.

 

배열로 받을 때, 총 9개의 난장이를 받아서 비교하려고 한다.

 

가장 쉽게 푸는 방법은 9개를 받아서 정렬하고 7개만 나오게하면 된다.

 

package back22y01;

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

public class sevenSmall {
	
	public static void main(String[] args) {
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			
			// 다 받는데 이제 compare로 비교해서 작은거 부터 출력해줘야함
			int[] arr = new int[9];
			
			for(int i =0; i< arr.length; i++) {
				arr[i] = Integer.parseInt(br.readLine());
			}
			
			Arrays.sort(arr);
			
			for(int i =0; i<7; i++) {
				System.out.println(arr[i]);
			}
			
		} catch (IOException e) {
			System.out.println("입출력 예외발생 : " + e.getMessage());
		} catch (Exception e) {
			System.out.println("예외발생 : " + e.getMessage());
		}
	}
}

틀렸다..

 

왜 틀렸을까? 일단 한 번 풀어보고 리팩토링 하는 방법으로 가려고 했는데..

 

문제 조건에 주어지는 키는 100을 넘지 않아야한다.

 

지금 코드는 그냥 9명 뽑아서 작은거 부터 7명을 뽑는 코드이다.

 

sum이란 변수를 둬서 100인 것을 확인해야 한다.

 

조합 가능한 모든 문자열을 하나씩 대입해 보는 방식으로 암호를 해독하는 방법. 

브루트 포스 방법을 사용해 본다.

 

인덱스를 검사할 때, 반복문을 이용해서 먼저 나오는 인덱스와 그 다음 인덱스를 하나씩 대입해 보면서 찾는 방법이다.

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

class Main {
	
	public static void main(String[] args) {
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			
			// 다 받는데 이제 compare로 비교해서 작은거 부터 출력해줘야함
			int[] arr = new int[9];
			int sum = 0;
			
			for(int i=0; i< arr.length; i++) {
				arr[i] = Integer.parseInt(br.readLine());
				sum += arr[i];
				System.out.println(sum + " sum 값 ");
			}
			
			Arrays.sort(arr);
			
			for(int i=0; i<arr.length - 1; i++) { // 마지막 전까지
				for(int j=i+1; j<arr.length; j++) { // 다음꺼 부터 마지막 까지
					if(sum - arr[i] - arr[j] == 100) { // 합계에서 첫번쨰하고 다음꺼를 뺴서 100이면
						System.out.println(sum + " sum 걸림");
						System.out.println(arr[i] + " i 걸림 이때 i 값 : " + i);
						System.out.println(arr[j] + " j 걸림 이때 j 값 : " + j);
						for(int k=0; k<arr.length; k++) { // 반복문으로 난쟁이들 키가 100이면 가짜 난쟁이들은 continue로 넘어가야함
							if(i == k || j == k) {
								System.out.println("안에서 걸리는 arr[i] 값 " + arr[i]); // i는 4 작은거부터 5번째
								System.out.println("안에서 걸리는 arr[j] 값 " + arr[j]); // j는 8 작은거부터 8번째
								continue;
							}
							System.out.println(arr[k]);
						}
					}
				}
			}
			
		} catch (IOException e) {
			System.out.println("입출력 예외발생 : " + e.getMessage());
		} catch (Exception e) {
			System.out.println("예외발생 : " + e.getMessage());
		}
	}
}

System.out.print 콘솔처럼 찍은 부분 뺴고 지웠는데도 실패했다.

 

System.exit(0);이 없어서 그랬던 것이다.

정상적인 종료를 해줘야하는데, 그렇지 못해서 틀렸다고 나온것 같다.

 

왜 틀린걸까? 종료를 안시키면 시간이 초과가 돼서 틀린걸까?

break;로 바꿔서 테스트를 해본다..

 

틀렸다고 나온다 어디선가 비정상적인 종료가 일어났다는건데.. 

 

			for(int i=0; i<arr.length - 1; i++) { 
				for(int j=i+1; j<arr.length; j++) { // 다음꺼 부터 마지막 까지
					if(sum - arr[i] - arr[j] == 100) { // 합계에서 첫번쨰하고 다음꺼를 뺴서 100이면
						for(int k=0; k<arr.length; k++) { // 반복문으로 난쟁이들 키가 100이면 가짜 난쟁이들은 continue로 넘어가야함
							if(i == k || j == k) {
								continue;
							}
							count++;
							System.out.println(arr[k]);
							if(count == 7) {
								br.close();
							}
							
						}
					}
				}
			}

버퍼리더가 println되면서 오류가 난 것은 아닐까 해서

강제적으로 count로 7까지 세주고 br.close()로 닫아보기도 하고, 그 밑에 br.close() 또는 break;로 막아봤지만 

해결하지 못했다.

 

아무래도 비정상적으로 종료되는 코드인 것 같은데..

 

System.exit(0); 으로 정상종료 하면 맞은 코드인데 이유를 알아야 한다.


Solution✍

 


Review🤩

백준 클래스이름은 항상 "Main"!!

 

 


 

 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

https://programmers.co.kr/learn/courses/30/lessons/17682

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr


Think🤔

문제 의도 파악하기.

 

다트 게임 기회 총 3번.

각 기회 0~10점.

S 1제곱, D 2제곱, T 3제곱 영역 존재.

옵션 스타상 * (해당 점수 , 그 전 점수)X2

옵션 아차상 # -해당점수

 

스타상 처음에 나올 시 첫 번째만 2배

스타상 점수 중첩될 시 4배가 될 수 있음.

 

스타상 , 아차상 중첩시 -2배

 

총 3번의 기회에서 얻은 값을 반환한다.

 

1. 방법

첫 번째 떠오른 방법은.. 반복문을 돌리고, 숫자가 나오면 if문을 이용해서 뒤에 문자를 제곱해주고 , 

tmp를 이용해서 옵션이 있을 경우 해당 인덱스 값을 넣어주고, 다음에도 나왔을 시, 그 전 위치도 옵션을 이용해 주는 방법이다.

>> 이 방법은 0~10점까지 존재하는데 10점이 나왔을 경우 '0'도 숫자로 인식해서 오버 스택이 발생할 수 있다.

 

보안 : 1인 경우(다음 인덱스가 숫자일 경우 10으로 취급)

 

2. 방법

두 번째 방법은.. 숫자를 먼저 분리를 시켜줘야 한다 어떻게 문자열을 3세트로 구분해줄까?

1S2D*3T

9S10D10T

옵션이 있어서 구분하는 방법이 1.방법 말고는 떠오르지 않는다. 일단 1방법을 이용해서 코드를 짜본다.

 

package program22y02;

import java.util.Arrays;

public class dart {
	public static void main(String[] args) {
		
		String dartResult = "1D2S#10S";
		
		// 48~57 0~9임
		
        int dRleng = dartResult.length(); // 다트 문자열 길이        
        int[] round = new int[3]; // 라운드 총 3
        
        int rNum = 0; // 현재 라운드
        for(int i=0; i<dRleng; i++){
            if((char)dartResult.charAt(i) > 47 && (char)dartResult.charAt(i) < 58){ // 0 ~ 9
            	System.out.println(dartResult.charAt(i));
                if(dartResult.charAt(i) == (char)49 && dartResult.charAt(i+1) == (char)48){ // 10인 경우
                    round[rNum] = i;
                    i++; // 다음 i도 넘김
                } else { // 10아닐때
                    round[rNum] = i;
                }
                System.out.println("i : " + i + ", rNum : " + rNum + ", dartResult.charAt(i) : " + dartResult.charAt(i));
                rNum++;
                System.out.println("ArrayIndex : " + i);
            } 
        }
        
        System.out.println(Arrays.toString(round));
	}
}

아스키코드를 이용해서 먼저 숫자들의 위치를 배열을 만들어서 집어 넣어 줬다.

 

처음 방법에서는 하나의 반복문으로 처리하려고 했지만, 그러면 안에 if문이 너무 많이 들어가게 돼서

일단은 각 라운드의 값을 배열로 받았다.

 

이 배열을 가지고 , 다음 배열 전까지 반복문을 돌고 그 값을 계산해준다.

 

int answer=0;
		// 48~57 0~9임
		
        int dRleng = dartResult.length(); // 다트 문자열 길이        
        int[] round = new int[4]; // 라운드 총 3 , 마지막에 문자열 마지막 길이를 넣어준다.
        int[] roundScore = new int[3]; // 라운드 스코어
        
        int rNum = 0; // 현재 라운드
        for(int i=0; i<dRleng; i++){
            if(dartResult.charAt(i) > 47 && dartResult.charAt(i) < 58){ // 0 ~ 9
                if(dartResult.charAt(i) == (char)49 && dartResult.charAt(i+1) == (char)48){ // 10인 경우
                    round[rNum] = i;
                    i++;
                } else { // 10아닐때
                    round[rNum] = i;
                }
                rNum++;
            } 
        }
        round[3] = dRleng;
        
        
        // 총 3라운드 진행
        for(int i=0; i<3; i++) {
        	int tmp = 0; // 계산을 하기 위한 tmp
        	for(int j=round[i]; j<round[i+1]; j++) {
        		int acha = 0; // 아차상 구하기
        		
        		if(dartResult.charAt(j) > 47 && dartResult.charAt(j) < 58) { // 숫자면 ~
        			if(dartResult.charAt(j) == (char)49 && dartResult.charAt(j+1) == (char)48) { // 10이면
        				tmp=10;
        				j++;
        			}else { // 0~9이면
        				tmp = dartResult.charAt(j) - '0';
        				System.out.println(tmp);
        			}
        		}else if(dartResult.charAt(j) == 'D') {
        			tmp = tmp*tmp;
        		} else if(dartResult.charAt(j) == 'T') {
        			tmp = tmp*tmp*tmp;
        		} else if(dartResult.charAt(j) == '*') {
        			if(i > 0) {
        				roundScore[i-1] = roundScore[i-1] * 2;
        			}
        			tmp = tmp*2;
        		} else if(dartResult.charAt(j) == '#') {
        			if(acha > 0) {
        				roundScore[acha] = roundScore[acha] * -1;
        			}
        			tmp = tmp * -1;
        			acha++; // 아차상 +1
        		}
        	}
        	roundScore[i] = tmp;
        }
        
        for(int i=0; i<3; i++) {
        	answer+=roundScore[i];
        }

일단 숫자별로 잘라주었다.

10인 경우를 if문해서 한번 더 처리하고 그 다음인덱스를 넘겨주기 위해서 i++로 처리 했다.

라운드 스코어를 총 4개를 주고, 마지막 라운드에는 dataResult의 마지막인덱스 값을 넣어줘서

 

반복문을 이용해서 

숫자부터 tmp에서 넣고

S인 경우는 넣지 않았음(어차피 1이기때문)

D인 경우 제곱 Math를 사용해도 되나, tmp*tmp도 가능

T인 경우도 마찬가지로 tmp*tmp*tmp 세제곱을 넣어주고,

 

int acha = 0; 

만약 라운드가 1라운드가 아닌, 2,3라운드 일 경우 '*'이 나온 더블 스코어(곱하기 2)를 해주고,

만약에 아차상(#)이 나온경우 마이너스를 해주는데, 전에 아차상이 존재한 값에는 -1를 또 곱해줘야 한다.

 

그렇게 나온 3개의 라운드를 answer에 다 더해주면 값이 나온다.


Solution✍

처음에는 라운드를 3개를 주려고 했지만, 마지막 인덱스값이 필요했기 때문에 round를 총 4개를 넣었다.


Review🤩

디버그를 찍으면서 중간에 .charAt부분에서 좀 헤맸지만 (char)48은 0인데 1로 해석했음..

디버그의 중요성을 다시 한번 느꼈다!!


 

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

https://programmers.co.kr/learn/courses/30/lessons/12912?language=java 

 

코딩테스트 연습 - 두 정수 사이의 합

두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요. 예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다. 제한 조건 a와 b가 같은 경우

programmers.co.kr


Think🤔

 

a = 3 , b = 5인 경우 , 3+4+5=12이므로 12를 리턴

 

사이에있는 값 다 더해서 리턴


Solution✍
class Solution {
    public long solution(int a, int b) {
        long answer = 0;
        if(a == b){
            return a;
        } 
        
        for(int i=Math.min(a,b); i<=Math.max(a,b); i++){
            answer+=i;
        }
        
        return answer;
    }
}

 

Review🤩

b가 더 클 수 있는 조건을 생각해야된다!

알고리즘 풀이 방법입니다.
문제(Problem) -> 생각(Think) -> 해결책(Solution) -> 리뷰(Review) 를 통해서 정리해서 작성합니다.
Problem📄

https://programmers.co.kr/learn/challenges?tab=all_challenges 

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr


Think🤔

루시와 엘라 찾기

최솟값 구하기

동명 동물 수 찾기

 

자세한 설명은 Solution 주석으로 대체


Solution✍
-- 코드를 입력하세요
SELECT A.DATETIME AS 시간
FROM (SELECT *
     FROM ANIMAL_INS
     ORDER BY DATETIME) AS A
WHERE ROWNUM = 1;

서브쿼리안에서 ★ 'AS' ★ 사용 하면 안됨

-- 코드를 입력하세요
SELECT A.DATETIME AS 시간
FROM (SELECT *
     FROM ANIMAL_INS
     ORDER BY DATETIME) A
WHERE ROWNUM = 1;
-- 코드를 입력하세요
SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE;

틀렸다고 나옴 뭐가 문제일까 ... ?

-- 코드를 입력하세요
SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE ASC;

ORDER BY의 위치는 SQL 문장의 항상 맨 마지막에 위치한다.
SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE (NAME LIKE 'Lucy' OR NAME LIKE 'Ella' OR NAME LIKE 'Pickle' OR NAME LIKE 'Rogan' OR NAME LIKE 'Mitty' OR NAME LIKE 'Sabrina')
ORDER BY ANIMAL_ID;

좀 더 줄이면 WHERE NAME IN () 사용할 수 있다

Review🤩

IN 함수로 살짝 변형할 수 있고, 서브쿼리 안에서 별칭 사용하는 것을 줄이도록 하자!


 

+ Recent posts