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

 

1027번: 고층 건물

세준시에는 고층 빌딩이 많다. 세준시의 서민 김지민은 가장 많은 고층 빌딩이 보이는 고층 빌딩을 찾으려고 한다. 빌딩은 총 N개가 있는데, 빌딩은 선분으로 나타낸다. i번째 빌딩 (1부터 시작)

www.acmicpc.net

코드설명

구현과 기하학(기울기) 문제입니다.

 

문제 로직입니다.

  1. 하나의 빌딩에서 좌측과 우측 빌딩을 내려봐야합니다.
  2. 좌측을 기준으로 하였을때 빌딩에서 멀어질수록 기울기가 더 작아져야 빌딩이 가리지 않고 보입니다.
  3. 우측을 기준으로 하였을떄 빌딩에서 멀어질수록 기울기가 더 커져야 빌딩이 가리지 않고 보입니다.

문제 구현중에서 유의해야할점들은,

 

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);
}
}

+ Recent posts