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

 

1027번: 고층 건물

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

www.acmicpc.net

문제

세준시에는 고층 빌딩이 많다. 세준시의 서민 김지민은 가장 많은 고층 빌딩이 보이는 고층 빌딩을 찾으려고 한다. 빌딩은 총 N개가 있는데, 빌딩은 선분으로 나타낸다. i번째 빌딩 (1부터 시작)은 (i,0)부터 (i,높이)의 선분으로 나타낼 수 있다. 고층 빌딩 A에서 다른 고층 빌딩 B가 볼 수 있는 빌딩이 되려면, 두 지붕을 잇는 선분이 A와 B를 제외한 다른 고층 빌딩을 지나거나 접하지 않아야 한다. 가장 많은 고층 빌딩이 보이는 빌딩을 구하고, 거기서 보이는 빌딩의 수를 출력하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 빌딩의 수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에 1번 빌딩부터 그 높이가 주어진다. 높이는 1,000,000,000보다 작거나 같은 자연수이다

 

 

출력

첫째 줄에 문제의 정답을 출력한다.

 

풀이

각 빌딩 간의 선분을 전부 찾고, 해당 선분들 중 가장 많은 종단점이 위치한 빌딩을 찾으면 된다.

 

먼저 (i1, h1)에서 (i2, h2)로 가는 선분이 i1 초과 i2 미만 구간에 속한 빌딩과 접촉하는지 안하는지 판별한다.

 

 

해당 선분의 방정식은 이렇다.

빌딩간 선분의 방정식

이 방정식의 i자리에 판별하고 싶은 빌딩의 위치를 입력해주면 그에 해당하는 선분의 h값과 빌딩의 높이를 비교하면서 가장 많은 종단점이 위치한 빌딩을 찾는다.

 

소스코드

 

더보기
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//백준 1027번 고층빌딩 골드 4
namespace BaekJoon_1027
{
    class Program
    {
        static void Main(string[] args)
        {
            //입력받기
            int N = int.Parse(Console.ReadLine());

            string[] raw_building = Console.ReadLine().Split(' ');

            double[] building = new double[N];
            for(int i = 0;i<N;i++)
                building[i] = double.Parse(raw_building[i]);

            //building의 인덱스가 i좌표, 해당 배열의 값이 높이라고 보면 된다.

            Solution(building, Combination(N), N);
            Console.ReadLine();

        }

        static List<int []> Combination(int N) {//주어진 수보다 작은 수들 2개씩 조합 뽑기(중복허용 X)
            List<int []> Combinate = new List<int []>();
            for (int i = 0; i < N; i++) { 
                for(int j = i+1;j<N;j++){
                    int [] a = {i, j};
                    Combinate.Add(a);
                    //Console.WriteLine(a[0] + ", "+ a[1]);
                }
            }
            return Combinate;
        }

        static void Solution(double[] building, List<int[]> comb, int N)
        {
            int[] count = new int[N];
            count.Initialize();

            for (int i = 0; i < comb.Count; i++) {//각 조합마다 연산한다.
                double y_dif = building[comb[i][1]] - building[comb[i][0]];
                double x_dif = comb[i][1] - comb[i][0];
                double vert = (building[comb[i][1]] - building[comb[i][0]]) / (comb[i][1] - comb[i][0]);//선분의 기울기.
                double y_mt = building[comb[i][0]] - comb[i][0] * vert;//선분의 y절편
                bool is_available = true;

                for (int j = comb[i][0] + 1; j < comb[i][1]; j++) { //두 빌딩 사이에 있는 빌딩들이 선분과 만나는지 비교한다.
                    if (building[j] >= vert * j + y_mt) { //빌딩이 해당 선분과 만난다면
                        is_available = false;
                        break;
                    }
                }

                if (is_available)//유효한 선분이면
                {
                    int[] a = { comb[i][0], comb[i][1] };
                    count[comb[i][0]]++;//두 빌딩의 볼 수 있는 빌딩 갯수를 1개씩 추가한다.
                    count[comb[i][1]]++;
                }
            }

            Array.Sort(count);//count배열 정렬 후 가장 큰값 출력.
            Console.WriteLine(count[N-1]);

            return;
        }
    }
}

'Algorithm > BaekJoon' 카테고리의 다른 글

[백준] 파이썬 알고리즘 풀이 1057번 - 토너먼트  (0) 2023.03.08

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

 

1057번: 토너먼트

김지민은 N명이 참가하는 스타 토너먼트에 진출했다. 토너먼트는 다음과 같이 진행된다. 일단 N명의 참가자는 번호가 1번부터 N번까지 배정받는다. 그러고 난 후에 서로 인접한 번호끼리 스타를

www.acmicpc.net

문제

김지민은 N명이 참가하는 스타 토너먼트에 진출했다. 토너먼트는 다음과 같이 진행된다. 일단 N명의 참가자는 번호가 1번부터 N번까지 배정받는다. 그러고 난 후에 서로 인접한 번호끼리 스타를 한다. 이긴 사람은 다음 라운드에 진출하고, 진 사람은 그 라운드에서 떨어진다. 만약 그 라운드의 참가자가 홀수명이라면, 마지막 번호를 가진 참가자는 다음 라운드로 자동 진출한다. 다음 라운드에선 다시 참가자의 번호를 1번부터 매긴다. 이때, 번호를 매기는 순서는 처음 번호의 순서를 유지하면서 1번부터 매긴다. 이 말은 1번과 2번이 스타를 해서 1번이 진출하고, 3번과 4번이 스타를 해서 4번이 진출했다면, 4번은 다음 라운드에서 번호 2번을 배정받는다. 번호를 다시 배정받은 후에 한 명만 남을 때까지 라운드를 계속 한다.

마침 이 스타 대회에 임한수도 참가했다. 김지민은 갑자기 스타 대회에서 우승하는 욕심은 없어지고, 몇 라운드에서 임한수와 대결하는지 궁금해졌다. 일단 김지민과 임한수는 서로 대결하기 전까지 항상 이긴다고 가정한다. 1 라운드에서 김지민의 번호와 임한수의 번호가 주어질 때, 과연 김지민과 임한수가 몇 라운드에서 대결하는지 출력하는 프로그램을 작성하시오.

 

 

 

풀이

스타 토너먼트의 총 라운드 수는 log(총 참가자 수)다.

라운드마다 승리하면 바뀌는 지민이와 한수의 번호를 가지고 비교해 만나는 라운드를 구하면 쉽게 풀 수 있다.

 

 

소스코드

 

더보기
n, jimin, hansoo= map(int, input().split())


rounds = ceil(log2(n))


if jimin > hansoo:
    mx = jimin
    mn = hansoo
else:
    mx = hansoo
    mn = jimin


result = 0
for i in range(rounds):
    if (mx-mn) == 1 and (mn%2) == 1:
        result = i+1
        break
    else:
        if mx%2 == 1: mx = (mx//2)+1
        else: mx = mx/2


        if mn%2 == 1: mn = (mn//2)+1
        else: mn = mn/2


print(result)

 

'Algorithm > BaekJoon' 카테고리의 다른 글

[백준] C# 알고리즘 풀이 1027번 - 고층 건물  (0) 2023.03.08

+ Recent posts