본문 바로가기
알고리즘/문제

줄자접기(더블릿 10F)

by jissi 2019. 11. 14.

문제

준성이는 1 cm 간격으로 눈금이 매겨져 있는 줄자를 가지고 있다.

그 줄자에 있는 서로 다른 눈금 6개에 한 눈금에 하나씩 점이 찍혀 있는데, 빨간 점, 파란 점, 노란 점이 각각 두 개씩 있다.

준성이는 먼저 두 빨간 점이 만나도록 줄자를 접었다. 그런 후 두 파란 점이 만나도록 줄자를 접고, 또다시 두 노란 점이 만나도록 줄자를 접었다. 줄자는 투명하여 접더라도 점들을 잘 볼 수 있다.

어떤 색깔의 두 점이 만나도록 줄자를 접었을 때, 그 다음에 접으려는 색깔의 두 점이 이미 만나고 있으면, 그 두 점에 대해서는 줄자를 접지 않는다.

예를 들어 길이 10 cm인 줄자에 아래 그림과 같이 2 cm와 7 cm 위치에 두 빨간 점이 찍혀 있고, 5 cm와 4 cm 위치에 파란 점이, 10 cm와 3 cm 위치에 노란 점이 찍혀 있다고 하자. (그림에서 빨간 점은 별표로, 파란 점은 동그라미, 그리고 노란 점은 네모로 표시되어 있다.)

빨간 두 점이 만나도록 줄자를 접으면 줄자의 4.5 cm 위치에서 접히고 4 cm와 5 cm 눈금이 서로 만나게 된다. 그러면 줄자의 왼쪽 부분의 길이는 4.5 cm이고 오른쪽 부분의 길이는 5.5 cm가 되어, 접힌 줄자의 길이는 5.5 cm가 된다. 파란 두 점은 이미 만나므로 줄자를 접지 않고, 그런 다음 노란 두 점이 만나도록 접으면 줄자의 길이는 3.5 cm가 된다.

줄자의 길이와 각 색깔의 점들이 찍혀있는 위치가 주어질 때, 준성이가 빨간 색, 파란 색, 노란 색의 순서로 두 점이 만나도록 줄자를 접으면 줄자의 길이가 얼마가 되는지를 구하는 프로그램을 작성하시오.

 

입력

 

  • 첫째 줄에 줄자의 길이가 입력된다. 줄자의 길이는 10 cm 이상 1,000 cm 이하이고 단위를 나타내는 cm은 입력되지 않는다.
  • 둘째 줄에는 두 빨간 점의 위치를 나타내는 정수가 빈칸을 사이에 두고 입력된다.
  • 셋째 줄에는 두 파란 점의 위치가,
  • 넷째 줄에는 두 노란 점의 위치를 나타내는 정수가 빈칸을 사이에 두고 입력된다.
  • 모든점의 위치는 다르다

 

 

출력

한 줄에 접은 후의 줄자의 길이를 소수점 이하 한자리까지 출력한다.

 

해설

2가지를 반복하면 된다. 

1. 접는다.

2. 점의 값을 줄자의 시작 위치 부터 다시 매긴다.

 

위 2가지를 3번 반복하면 되는데

접히는 부분이 맨 앞으로 가는 경우(->방향으로 접는 경우) 시작부분이 기존 줄자의 0.5 부분의 있게되므로 계산이 어려워진다.

그러므로 모든 접는 방향은 (<-뱡향으로 접는다)

 

이를 알았으면 쉽다.

먼저 두가지 경우로 나눈다. 접히는 점을 기준으로 오른쪽이 긴 경우, 왼쪽이 긴 경우

접히는 점 왼쪽을 left 접히는점 오른쪽을 right라고 하겠다.

 

오른쪽이 긴 경우

left 부분은 접히고 나서 다시 위치를 매길때 값이 커진다. 그러므로 그 값을 기존의 점에 추가 시켜 주면 된다.

right부분은 제일 마지막에 있는 부분이 0으로 바뀌므로 마지막까지의 거리가 접히고 나서 새로운 위치 값이 된다.

 

왼쪽이 긴 경우 

left 부분은 바뀌는것이 없다.

right 부분은 중간값을 기준으로 현재 위치와의 거리만큼 중간값에서 빼주면 된다.

 

코드

#include <iostream>
#include <algorithm>

using namespace std;

int point[3][2];
int main(void)
{
  double length;
  cin>>length;
  double mid;
  for(int i = 0 ; i < 3; i ++){
    cin>>point[i][0]>>point[i][1];
  }
  for(int i = 0 ; i < 3; i++){
    if(point[i][0] != point[i][1]){
      mid = (double)(point[i][0] + point[i][1]) / 2;
      if(mid < length/2){
        for(int j = i + 1; j < 3 ; j++){
          for(int k = 0 ; k < 2 ; k++){
            if(point[j][k] <= mid){
              point[j][k] += (length - mid * 2);
            }
            else{
              point[j][k] = length - point[j][k]; 
            }
          }
        }
        length-= mid;
      }
      else{
        for(int j = i + 1 ; j < 3 ; j++){
          for(int k = 0 ; k < 2 ; k++){
            if(point[j][k] > mid)
              point[j][k] = mid - (point[j][k] - mid);
          }
        }
        length = mid;
      }
    }
  }
  printf("%0.1f", length);
  return 0;
}

 

github : https://github.com/ji3427/algorithm/blob/master/week1/dov_10_measure.cpp

'알고리즘 > 문제' 카테고리의 다른 글

건조(더블릿 10F)  (0) 2019.11.13

댓글