https://www.acmicpc.net/problem/1027
1027번: 고층 건물
세준시에는 고층 빌딩이 많다. 세준시의 서민 김지민은 가장 많은 고층 빌딩이 보이는 고층 빌딩을 찾으려고 한다. 빌딩은 총 N개가 있는데, 빌딩은 선분으로 나타낸다. i번째 빌딩 (1부터 시작)
www.acmicpc.net
코드설명
구현과 기하학(기울기) 문제입니다.
문제 로직입니다.
- 하나의 빌딩에서 좌측과 우측 빌딩을 내려봐야합니다.
- 좌측을 기준으로 하였을때 빌딩에서 멀어질수록 기울기가 더 작아져야 빌딩이 가리지 않고 보입니다.
- 우측을 기준으로 하였을떄 빌딩에서 멀어질수록 기울기가 더 커져야 빌딩이 가리지 않고 보입니다.
문제 구현중에서 유의해야할점들은,
1. 처음 기울기 처리 ( i == idx - 1 )
//기준좌표에서 왼쪽빌딩 확인 ( 기울기가 더 작아져야합니다. ) for(int i=idx - 1; i >=0; i--) { //기울기 : ( 기준의 가로좌표 - 비교의 가로좌표 ) * ( 기준의 세로좌표 - 비교의 세로좌표 ) double inclination = (double) ( arr[idx] - arr[i] ) / ( idx - i ); //이전 기울기와 비교하여 기울기가 더 작아져야합니다. if( standardInclination > inclination || i == idx - 1) { cnt += 1; standardInclination = inclination; } }
- 여기서 처음에 i == idx -1 이 아닌, standardInclination == 0 일경우로 생각하여 진행했지만, standardInclination 이 계산도중 0 으로 변경되어 연산이 더 지속될 수 잇으므로 i == idx - 1 로 처리하여 첫번째 경우로 처리하도록 합니다.
2. 기울기가 크거나 같은경우가 아닌 큰 경우나 작은경우만 작동합니다.
if( standardInclination > inclination || i == idx - 1) {
- 처음에 standardInclination >= inclination 으로 처리하였으나, 기울기가 같을경우 해당 빌딩은 가려져서 보이지 않습니다.
3. 처음에는 while문으로 접근하여 진행했는데, 이 문제 같은경우 for문으로 Indexing처리하며 하나씩 내려오도록 처리하는것이 효율적입니다. 추가로, 특정 조건에 맞지 않을경우 for문을 break하도록 처리하였었는데, 이 문제같은경우 if문안의 조건에 일치한다면 성공하도록 하는 로직이 훨씬 더 논리가 간결해집니다.
또한, 왼쪽의 기울기를 살펴본다고 했을때 현재 보이지않는다고해도 다른 멀리 있는 건물이 보일 수 있기에 모든 건물을 다 확인해야합니다.
beforeHeight_Weight = Integer.MIN_VALUE; //기울기가 더 커져야 합니다. while(right <= N - 1) { // System.out.println(arr[right]+" "); double height_weight = (double) ( arr[start] - arr[right]) / ( start - right ); //기울기가 더 커져야만 합니다. if(beforeHeight_Weight < height_weight || right == start + 1) { beforeHeight_Weight = height_weight; result += 1; } right += 1; }
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static int N, M; public static int[] arr; public static int answer = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); arr = new int[N]; for(int i=0;i<N;i++) { arr[i] = Integer.parseInt(st.nextToken()); } for(int i=0;i<N;i++) { simulate(i); } System.out.println(answer); } public static void simulate(int idx) { double standardInclination = 0; int cnt = 0; //기준좌표에서 왼쪽빌딩 확인 ( 기울기가 더 작아져야합니다. ) for(int i=idx - 1; i >=0; i--) { //기울기 : ( 기준의 가로좌표 - 비교의 가로좌표 ) * ( 기준의 세로좌표 - 비교의 세로좌표 ) double inclination = (double) ( arr[idx] - arr[i] ) / ( idx - i ); //이전 기울기와 비교하여 기울기가 더 작아져야합니다. if( standardInclination > inclination || i == idx - 1) { cnt += 1; standardInclination = inclination; } } standardInclination = 0; //기준좌표에서 오른쪽빌딩 확인 ( 기울기가 더 커져야 합니다. ) for(int i=idx + 1; i < N; i++) { //기울기 : ( 기준의 가로좌표 - 비교의 가로좌표 ) * ( 기준의 세로좌표 - 비교의 세로좌표 ) double inclination = (double) ( arr[idx] - arr[i] ) / ( idx - i ); //이전 기울기와 비교하여 기울기가 더 커져야 합니다. if( standardInclination < inclination || i == idx + 1) { cnt += 1; standardInclination = inclination; } } answer = Math.max(answer, cnt); } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 14891 톱니바퀴 - 구현 + 시뮬레이션 JAVA (0) | 2023.08.15 |
---|---|
[백준] 9372 상근이의 여행 - 그래프 + DFS JAVA (0) | 2023.08.14 |
[백준] 9935 문자열 폭발 - StringBuilder + 아이디어 JAVA (0) | 2023.08.12 |
[백준] 1987 알파벳 - Backtracking(백트래킹) + DFS(깊이우선탐색) + HashSet(해시셋) JAVA (0) | 2023.08.12 |
[백준] 7490 0 만들기 - 완전탐색 + 문자열 + stringtokenizer JAVA (0) | 2023.08.11 |