[백준] 14717 앉았다 JAVA

·2024년 3월 15일

1일1백준 -Java-

목록 보기
52/60

문제


입력

영학이의 패를 뜻하는 두 개의 정수 A, B가 주어진다. (1 ≤ A, B ≤ 10)

출력

영학이가 이길 확률을 소수점 이하 셋 째 자리까지 반올림해서 출력하시오.

반드시 뒤따르는 0도 출력해야 한다. 예를 들어, '0.700'을 출력했다면 정답이고, '0.7'을 출력했다면 오답이다.

예제 입력

1 1

예제 출력

0.941

내가 했던 풀이 방법

  1. list에 1~10까지의 숫자 카드를 2개씩 넣어둔다.

  2. 입력받은 숫자(내가 가지고 있는 카드)를 list에서 제외해준다.

  3. 내가 가지고 있는 카드가 같은 숫자일 시, isDdang(땡인지 아닌지)를 true로 설정해준다.

  4. 내가 땡일 때는 내가 질 case를 계산해서 전체 case에서 빼주는 게 계산이 단순하고, 내가 끗일 때는 상대가 질 case를 계산해주는 게 계산이 단순함.

  5. 내가 N땡일 때 : 1) N을 계산해준다. (내가 가지고 있는 카드 값) 2) 전체 카드 중에 N보다 크면서 두 카드가 같은 숫자일 때 cases를 1씩 증가시켜준다. (이때 for문의 범위는 size()-1로 해야한다. (마지막은 확인할 필요가 없음. -> 바로 앞 index와 같지 않을 경우 의미가 없고, 앞에서 같다고 판단했으면 이미 cases가 올라갔기 때문에))

  6. 내가 N끗일 때 : 1) N을 계산해준다. (내가 가지고 있는 카드 합에서 10으로 나눈 나머지) 2) 이중 for문을 이용해 두 카드의 합의 일의자리가 N보다 작고 둘의 값이 같지 않을 때 cases를 1 증가시켜준다.
    (이때 for문을 도는 index i와 j는 같으면 안 된다. (카드가 중복되면 안 되기 때문에) 또한, [1, 9]와 [9, 1]은 같은 경우이므로, 제외해줘야 한다. (모든 경우는 왼쪽 숫자가 오른쪽 숫자보다 더 작거나 같도록 (i<=j) 조건을 넣어 제외시켜주었다.))

  7. 전체 경우의 수 153(18C2)에서 현재 cases가 나올 확률을 계산하여 소수점 3자리까지 출력해준다.

코드

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

public class Main {
    public static void main(String[] args) throws IOException {

        List<Integer> all_card = new ArrayList<>(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10));

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");

        int card1 = Integer.parseInt(input[0]);
        int card2 = Integer.parseInt(input[1]);

        all_card.remove(Integer.valueOf(card1));
        all_card.remove(Integer.valueOf(card2));

        boolean isDdang = (card1==card2);
        double cases = 0;
        int my = 0; // 땡/끗 앞에 붙는 숫자
        if(isDdang) {
            my = card1;
            for(int i=0; i<all_card.size()-1; i++) {
                if(all_card.get(i+1)==all_card.get(i) && all_card.get(i)>card1) {
                    cases++;
                }
            }
            cases = 153-cases;
        } else {
            my = (card1+card2)%10;
            for(int i=0; i<all_card.size(); i++) {
                for(int j=0; j<all_card.size(); j++) {
                    if(i==j) continue;
                    if(i<=j) {
                        if((((all_card.get(i)+all_card.get(j))%10)<my) && all_card.get(i)!=all_card.get(j)) {
                            cases++;
                        }
                    }    
                }
            }
        }

        double probability = cases/153;
        System.out.printf("%.3f", probability);
    }   
}

회고

일단 처음 문제를 접했을 때 확률 계산하는 부분에서 이해를 잘 못했다. 왜 1 1을 입력했을 때 0.941 확률인지 이해를 하지 못했다. 문제 자체가 제출한 사람도 적어서 참고할만한 것도 마땅하지 않았는데, 질문게시판에서 힌트를 받아서 풀이할 수 있었다. 내가 땡일 때 계산은 정말 쉬운 편인데, 끗일 때 계산이 쉽지 않았다. 사실 아직 이해를 못하는 부분 중에 하나는 이길 확률이라 내가 비길 때도 포함해서 계산했는데 비길 때를 제외해야 값이 나와서 그렇게 제출했다. 비기는 건 지는 게 아니라 넘어가는건가... (흐음) 이 문제를 풀면서 조합을 내가 잘 모르고 있구나를 느껴서 조합 관련 문제도 몇 개 더 풀어봐야겠다라는 걸 느꼈다. 그리고 여러모로 몰랐던 부분이 있었기 때문에 정리하고 가겠다.

List에서 특정 값 삭제

remove()

remove(int index)
remove() 메소드의 파라미터로 int를 전달하면,
해당 index의 값이 삭제됩니다.

remove(Object o)
remove() 메소드의 파라미터로 Object 객체를 전달하면,
List에서 해당 객체를 찾아서 첫 번째로 나오는 값만 삭제합니다.
값을 삭제하면 true를 리턴하고, 만약 삭제할 값이 없으면 false를 리턴합니다.

만약 list 중에 1을 삭제하고 싶을 경우 어떻게 할까

all_card.remove(Integer.valueOf(card1));

이번 코드에서는 다음과 같이 Integer 객체를 전달했다.

removeAll()

파라미터로 넘겨 준 Collection 객체에 담긴 element를 모두 삭제합니다.
즉, [1, 2, 3, 4, 5, 5] 배열에서 5를 전부 삭제하고 싶을 땐 removeAll을 사용해주면 된다.

Arrays.asList()

List<Integer> all_card = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10);

처음 코드를 작성할 때 다음과 같이 list를 만들어줬다.

Exception in thread "main" java.lang.UnsupportedOperationException

코드를 실행하고 나니 지원하지 않는 연산이라는 에러가 떴다.
이를 찾아보니 asList를 사용할 경우 add/remove를 사용할 수 없다고 한다. List 객체를 생성할 때 요소를 제거 할 수 없는 고정된 목록으로 생성하기 때문이다.

add/remove를 사용하기 위해서는

List<Integer> all_card = new ArrayList<>(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10));

다음과 같이 ArraysList 나 LinkedList 등의 컬렉션 클래스로 한번 Wrapping 해서 사용하면 된다.

참고 자료

[Java] ArrayList에서 특정 값 삭제하기
Collection remove에 대해

profile
Frontend🍓

0개의 댓글