문제
준성이는 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 |
---|
댓글