일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Java
- spring
- K-디지털트레이닝
- dbeaver
- 글로벌소프트웨어캠퍼스
- https
- 도메인
- 우리FISA
- 리눅스
- M2
- sts
- springboot
- mysql
- 클라우드 서비스 개발
- AWS
- route 53
- 우리FISA #
- 맥북
- 우리에프아이에스
- jdk
- 클라우드 서비스 개발 #
- 로드밸런스
- 우리에프아이에스 #
- HTTP
- Gradle
- 맥OS
- 우리FIS아카데미 #
- 우리FIS아카데미
- 맥
- Today
- Total
<<개발일지>>
[백준/1002/실버3] 터렛 본문
https://www.acmicpc.net/problem/1002
1002번: 터렛
각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 $-1$ 출력한다.
www.acmicpc.net
<<풀이>>
레벨: 실버 3
시간 복잡도 : O(N)
시간: 284ms
주요 개념 : Math.sqrt, continue, ArrayList, 두 개의 원이 한 원의 내부에 있을 때 바깥에 있을 때 구분
이 문제는 단순 구현 문제이면서 옛날에 배운 수학적인 지식이 필요한 문제이다. 너무 오랜만에 접하니 경우의 수를 두 원이 밖에서 겹치고 접하고 등을 계산해서 처음에 구했다가 틀렸다가 나왔다. 알고 보니, 두 개의 원 중 한 원이 내부에서 겹치는 조건도 포함을 시켰어야 했다.
그래서 이를 추가하고 문제를 접근을 해서 결과적으로 풀은 줄 알았는데, 또 틀렸다가 나왔다... ㅋ ㅠ
바로 무한히 겹칠 때 -1로 출력하라는 부분 때문이었다. 나는 하나 겹칠때, 두 개 겹칠때, 하나도 안 겹칠 때를 제외하면 무조건 -1이 출력이 된다고 생각했다. 하지만 이는 잘못된 생각이었고 완전히 겹치는 경우는 중심 점과 반지름 길이 전부가 같은데 이는 내가 구현한 코드에서는 1를 도출해서 list에 넣어줘버리는 문제가 발생했다.
그래서 사전에 완전히 겹치는 경우를 제외시키고 시작했다.
if(x[0]==x[3] && x[1]==x[4] && x[2]==x[5]) {
answer.add(-1);
continue;
}
바로 이 부분이다. 이렇게 풀었더니 무사히 맞출 수가 있었다.
import java.util.ArrayList;
import java.util.Scanner;
class Main {
private ArrayList<Integer> solution(ArrayList<int[]> list2) {
ArrayList<Integer> answer = new ArrayList<>();
for (int[] x : list2) {
if(x[0]==x[3] && x[1]==x[4] && x[2]==x[5]) {
answer.add(-1);
continue;
}
if(Math.sqrt((x[0]-x[3])*(x[0]-x[3]) + (x[1]-x[4])*(x[1]-x[4])) > Math.max(x[2], x[5])) {
if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) == (x[2] + x[5])) {
answer.add(1);
} else if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) < (x[2] + x[5])) {
answer.add(2);
} else if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) > (x[2] + x[5])) {
answer.add(0);
}
} else {
if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) + Math.min(x[2], x[5]) == Math.max(x[2], x[5])) {
answer.add(1);
} else if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) + Math.min(x[2], x[5]) > Math.max(x[2], x[5])) {
answer.add(2);
} else if (Math.sqrt((x[0] - x[3]) * (x[0] - x[3]) + (x[1] - x[4]) * (x[1] - x[4])) + Math.min(x[2], x[5]) < Math.max(x[2], x[5])) {
answer.add(0);
}
}
}
return answer;
}
public static void main(String[] args) {
Main T = new Main();
Scanner in = new Scanner(System.in);
int test = in.nextInt();
ArrayList<int[]> list1 = new ArrayList<>();
ArrayList<int[]> list2 = new ArrayList<>();
for (int i = 0; i < test; i++) {
list1.add(new int[6]);
}
for(int[] a : list1) {
for (int i = 0; i < 6; i++) {
a[i] = in.nextInt();
}
list2.add(a);
}
for (int answer : T.solution(list2) ) {
System.out.println(answer);
}
}
}
다른 사람들은 나 284ms보다 빠르게 구현을 한 거 같은데 한 번 찾아봐야겠다 !
<<추가 공부>>
까먹어서 다시 한 번 정리하고 간다!!
break : 돌고 있던 반복문을 완전히 종료 시키고 다음 단계를 진행한다.
continue : 더이상 밑으로 진행하지 않고 for문의 다음 단계를 진행한다.
return: 메서드 전체를 종료시킨다.
좀 더 디테일한 정리
- break: 현재 실행 중인 반복문 (예: for, while, do-while 루프)을 완전히 종료시키고, 반복문 바로 다음에 위치한 코드의 실행을 계속합니다. switch 문 내에서도 사용되어, case 블록의 실행을 종료하고 switch 문을 빠져나옵니다.
- continue: continue가 포함된 반복문의 현재 실행 중인 반복을 즉시 종료하고, 반복문의 다음 반복으로 건너뛰어 계속 실행합니다. for 루프의 경우, 증감식으로 이동하고, while 또는 do-while 루프의 경우, 조건식으로 돌아갑니다.
- return: 현재 실행 중인 메서드를 종료하고, 메서드를 호출한 곳으로 제어를 반환합니다. void 메서드에서는 단순히 메서드 실행을 종료하며, 반환 타입이 있는 메서드에서는 값을 반환합니다. return 문을 만나면, 그 문장 이후의 메서드 내 코드는 실행되지 않습니다.
'코딩테스트' 카테고리의 다른 글
[백준/1003/실버3] 피보나치 함수 (6) | 2024.03.01 |
---|---|
[DFS] 7. 조합의 경우수(메모이제이션) (6) | 2024.02.26 |
[DFS] 6. 순열 구하기 (83) | 2024.02.24 |
[DFS] 5. 동전교환 (6) | 2024.02.24 |
[백준/1051/실버3] 숫자 정사각형 (1) | 2024.02.22 |