Programmers
[프로그래머스 Level.2] 시소 짝꿍 (연습문제) (Java)
Devtraces
2023. 1. 31. 18:37
문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/152996
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
코딩테스트 연습 > 연습문제 > 시소 짝꿍
문제 설명
어느 공원 놀이터에는 시소가 하나 설치되어 있습니다. 이 시소는 중심으로부터 2(m), 3(m), 4(m) 거리의 지점에 좌석이 하나씩 있습니다.
이 시소를 두 명이 마주 보고 탄다고 할 때, 시소가 평형인 상태에서 각각에 의해 시소에 걸리는 토크의 크기가 서로 상쇄되어 완전한 균형을 이룰 수 있다면 그 두 사람을 시소 짝꿍이라고 합니다. 즉, 탑승한 사람의 무게와 시소 축과 좌석 간의 거리의 곱이 양쪽 다 같다면 시소 짝꿍이라고 할 수 있습니다.
사람들의 몸무게 목록 weights이 주어질 때, 시소 짝꿍이 몇 쌍 존재하는지 구하여 return 하도록 solution 함수를 완성해주세요.
제한 사항
- 2 ≤ weights의 길이 ≤ 100,000
- 100 ≤ weights[i] ≤ 1,000
- 몸무게 단위는 N(뉴턴)으로 주어집니다.
- 몸무게는 모두 정수입니다.
입출력 예weightsresult
[100,180,360,100,270] | 4 |
입출력 예 설명
{100, 100} 은 서로 같은 거리에 마주보고 앉으면 균형을 이룹니다.
{180, 360} 은 각각 4(m), 2(m) 거리에 마주보고 앉으면 균형을 이룹니다.
{180, 270} 은 각각 3(m), 2(m) 거리에 마주보고 앉으면 균형을 이룹니다.
{270, 360} 은 각각 4(m), 3(m) 거리에 마주보고 앉으면 균형을 이룹니다.
나의 코드
import java.util.*;
class Solution {
public long solution(int[] weights) {
long answer = 0;
Map<Integer, Integer> map = new HashMap<>();
for(int i=0; i<weights.length; i++) {
map.put(weights[i], map.getOrDefault(weights[i], 0) + 1);
}
for(int i=0; i<weights.length; i++) {
if(map.get(weights[i]) > 1) answer += map.get(weights[i]) - 1;
int weight2 = weights[i] * 2;
if(weight2 % 3 == 0) answer += map.getOrDefault(weight2 / 3, 0);
if(weight2 % 4 == 0) answer += map.getOrDefault(weight2 / 4, 0);
int weight3 = weights[i] * 3;
if(weight3 % 2 == 0) answer += map.getOrDefault(weight3 / 2, 0);
if(weight3 % 4 == 0) answer += map.getOrDefault(weight3 / 4, 0);
int weight4 = weights[i] * 4;
if(weight4 % 2 == 0) answer += map.getOrDefault(weight4 / 2, 0);
if(weight4 % 3 == 0) answer += map.getOrDefault(weight4 / 3, 0);
}
return answer / 2;
}
}
풀이
- weights의 값의 갯수를 저장하기 위해 Map을 생성하고 weights를 for문을 돌면서 getOrDefault()를 이용하여 해당 몸무게의 개수를 저장한다.
- 이제 다시 weights를 for문을 돌면서 해당 몸무게(weight)가 2m, 3m, 4m의 거리에 탔을 때 반대쪽 시소 2m, 3m, 4m에 균형을 이루는 상대방의 몸무게(x)가 Map에 담겨있는지 확인하여 갯수를 가져오면 된다.
- 우선 수학적으로 모든 경우의 수를 정리해보자.
2m : weight = 2m : x => x = weight
2m : weight = 3m : x => x = 3m * weight / 2m
2m : weight = 4m : x => x = 4m * weight / 2m
3m : weight = 2m : x => x = 2m * weight / 3m
3m : weight = 3m : x => x = weight
3m : weight = 4m : x => x = 4m * weight / 3m
4m : weight = 2m : x => x = 2m * weight / 4m
4m : weight = 3m : x => x = 3m * weight / 4m
4m : weight = 4m : x => x = weight - 따라서 총 7가지의 경우를 체크해보면 된다.
- 우선 x = weight인 경우를 확인하기 위해 Map에서 weight의 개수가 2 이상이라면 자기 자신 말고 같은 몸무게가 더 있다는 뜻이므로 map에서 해당 weight의 개수를 꺼내 -1하여 answer에 더해준다.
- 다음은 x = 2m * weight / 3m 와 x = 2m * weight / 4m 인 경우를 확인하기 위해서 weight에 2를 곱하고 해당 값이 3으로 나누어진다면 3으로 나눈 값이 Map에 있다면 해당 값의 개수인 value를 가져오고 아니라면 0을 가져와 answer에 더한다. 마찬가지로 weight에 2를 곱한 값이 4로 나누어지는지 확인하여 똑같이 진행한다.
- 다음으로 x = 3m * weight / 2m 와 x = 3m * weight / 4m 인 경우를 확인하기 위해서 weight에 3을 곱하고 해당 값이 2로 나누어지는지, 4로 나누어지는지 확인하고 똑같이 진행한다.
- 마지막으로 x = 4m * weight / 2m 와 x = 4m * weight / 3m 인 경우를 확인하기 위해서 weight에 4를 곱하고 해당 값이 2로 나누어지는지, 3으로 나누어지는지 확인하고 똑같이 진행한다.
- 이렇게 모든 경우를 확인하여 해당 몸무게가 Map에 있다면 해당 몸무게의 개수를 answer에 더해주면 된다.
- 이 때, weights에서 2명을 뽑아 균형을 이루는 쌍을 구하는 것인데 weights를 전부 돌면서 확인하여 모든 개수를 구해 더해주어 자기 몸무게일 때와 상대방 몸무게일 때 모두 포함하여 계산했기 때문에 answer / 2를 최종적으로 반환하면 된다.