이런저런 IT 이야기
Programming Challenges #28 본문
교수들은 각종 업무와 약속으로 가득 찬 복잡한 스케줄 속에서 매우 바쁘게 살아간다. p 교수는 낮잠을 자는걸 좋아하지만 스케줄이 바쁘다 보니 낮잠을 잘 수 있는 시간이 별로 없다. 하지만 p교수는 매일 한 번씩은 낮잠을 자고 싶어한다. 물론 그의 스케줄을 감안해서 될 수 있으면 오래동안 낮잠을 즐길 수 있는 방법을 찾아야 한다. p교수가 최대한 오래동안 낮잠을 잘 수 있는 프로그램을 만들어라.
입력 값
입력은 임의 개수의 테스트 케이스가 입력되며 각 테스트 케이스가 하루를 나타낸다. 각 테스트 케이스 첫번째 줄에는 100이하의 양의 정수 s가 있으며, 이 수는 그날 미리 잡혀있는 약속의 갯수이다. 그 다음 줄 부터 s개의 줄에는 'time1 ~ time2 약속내용' 형식으로 잡혀 있는 약속이 입력되며, time1은 시작 시간, time2는 종료 시간을 나타낸다. 모든 시간은 hh:mm으로 표시된다. 종료 시간은 시작 시간보다 뒤에 있어야 한다. 모든 시간은 10:00 이후 18:00 이전으로 주어진다. 따라서 결과도 반드시 이 시간 내에 있어야 한다. 즉 10:00전에 낮잠을 잘 수 없으며, 18:00 넘어서까지 낮잠을 잘 수 없다. 약속은 임의 문자를 열거한 형태로 주어지는데 반드시 한 줄에 입력되어야 한다. 각 줄의 길이는 255글자를 넘지 않는다. 하지만 약속이 정해진 순서대로 입력된다고 가정할 수 없다.
결과:
function findLongestNap(schedules) {
const dayStart = "10:00";
const dayEnd = "18:00";
// 시간을 분 단위로 변환
const toMinutes = (time) => {
const [hours, minutes] = time.split(":").map(Number);
return hours * 60 + minutes;
};
// 분 단위를 시간으로 변환
const toTime = (minutes) => {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
const paddedHours = String(hours).padStart(2, "0");
const paddedMins = String(mins).padStart(2, "0");
return `${paddedHours}:${paddedMins}`;
};
let longestNapStart = toMinutes(dayStart);
let longestNapDuration = 0;
// 스케줄을 분 단위로 변환하여 정렬
const sortedSchedules = schedules.map((schedule) => {
const [time1, time2] = schedule.split(" ")[0].split("~");
const start = toMinutes(time1);
const end = toMinutes(time2);
return { start, end };
}).sort((a, b) => a.start - b.start);
// 낮잠 가능한 시간대 찾기
for (let i = 1; i < sortedSchedules.length; i++) {
const currentStart = sortedSchedules[i - 1].end;
const currentEnd = sortedSchedules[i].start;
const napDuration = currentEnd - currentStart;
if (napDuration > longestNapDuration) {
longestNapStart = currentStart;
longestNapDuration = napDuration;
}
}
// 첫번째 스케줄 시작 시간과 마지막 스케줄 종료 시간과의 비교
const firstScheduleStart = sortedSchedules[0].start;
const lastScheduleEnd = sortedSchedules[sortedSchedules.length - 1].end;
const firstNapDuration = firstScheduleStart - toMinutes(dayStart);
const lastNapDuration = toMinutes(dayEnd) - lastScheduleEnd;
if (firstNapDuration > longestNapDuration) {
longestNapStart = toMinutes(dayStart);
longestNapDuration = firstNapDuration;
}
if (lastNapDuration > longestNapDuration) {
longestNapStart = lastScheduleEnd;
longestNapDuration = lastNapDuration;
}
return toTime(longestNapStart) + " ~ " + toTime(longestNapStart + longestNapDuration);
}
// 입력 받기
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("테스트 케이스 개수를 입력하세요: ", (t) => {
const schedules = [];
const getSchedule = (i) => {
rl.question(`테스트 케이스 ${i + 1}의 약속 개수를 입력하세요: `, (s) => {
const schedule = [];
const getScheduleInfo = (j) => {
rl.question(`약속 ${j + 1}의 시간과 내용을 입력하세요: `, (info) => {
schedule.push(info);
if (j + 1 < s) {
getScheduleInfo(j + 1);
} else {
schedules.push(schedule.join('\n'));
if (i + 1 < t) {
getSchedule(i + 1);
} else {
// 모든 입력 완료
rl.close();
// 각 테스트 케이스에 대해 최대 낮잠 시간 계산 및 출력
for (let k = 0; k < schedules.length; k++) {
const result = findLongestNap(schedules[k].split('\n'));
console.log(`테스트 케이스 ${k + 1}: ${result}`);
}
}
}
});
};
getScheduleInfo(0);
});
};
getSchedule(0);
});
입력:
3
10:00 ~ 11:30 meeting
14:00 ~ 15:30 study
16:00 ~ 17:00 appointment
2
11:00 ~ 13:00 lunch
14:30 ~ 16:00 work
출력:
11:30 ~ 14:00
13:00 ~ 14:30
해설:
첫 번째 테스트 케이스에서는 스케줄이 3개 있으며, 낮잠을 즐길 수 있는 시간은 11:30부터 14:00까지이다.
두 번째 테스트 케이스에서는 스케줄이 2개 있으며, 낮잠을 즐길 수 있는 시간은 13:00부터 14:30까지이다.
'Algorithm' 카테고리의 다른 글
외판원 순회 문제 (Traveling Salesman Problem, TSP) (0) | 2023.05.23 |
---|---|
Programming Challenges #31 (0) | 2023.05.23 |
Programming Challenges #30 (0) | 2023.05.22 |
Programming Challenges #29 (0) | 2023.05.22 |
Programming Challenges #27 (0) | 2023.05.22 |