{ }codelper
negative remainderadditionP0166

Meeting time in cities around the world

People from cities around the world join one video meeting. The first line gives the meeting's start time in Coordinated Universal Time (UTC), HH:MM, and its length D in minutes, separated by a space. The second line gives the number of cities n, and each of the next n lines gives a city name and that city's offset, separated by a space. An offset has the form "+HH:MM" or "-HH:MM", and the city's time is the UTC time plus the offset. The sign applies to both the hours and the minutes.
For example, "-03:30" means subtract 3 hours 30 minutes. An offset of zero is written "+00:00". For each city, find the local time at which the meeting starts and the local time at which it ends. The end time is the start time plus D minutes. For each time, also find the day difference: an integer saying how many days the city's date is after the UTC date at the moment the meeting starts; one day before is -1. For each city, in input order, print one line with the name, start time, start day difference, end time and end day difference, separated by single spaces. Write times as HH:MM (two digits for both hours and minutes, 00:00 to 23:59). Write a day difference with "+" in front if it is above 0 (+1), as 0 if it is 0, and like -1 if it is below 0. On the last line print the number of cities whose start and end day differences are different, that is, the cities where midnight passes during the meeting.

Input
00:00 ≤ start time ≤ 23:59, 1 ≤ D ≤ 1,440, 1 ≤ n ≤ 1,000, city names are 1 to 20 English letters, -12:00 ≤ offset ≤ +14:00 and the offset's minutes are one of 00, 15, 30, 45
Output
One line per city (name, start time, day difference, end time, day difference), then the number of cities where midnight passes
Example 1 · stdin
01:10 120
5
Seoul +09:00
Noronha -02:00
StJohns -03:30
Kathmandu +05:45
Kiritimati +14:00
stdout
Seoul 10:10 0 12:10 0
Noronha 23:10 -1 01:10 0
StJohns 21:40 -1 23:40 -1
Kathmandu 06:55 0 08:55 0
Kiritimati 15:10 0 17:10 0
1
Example 2 · stdin
23:30 1440
3
London +00:00
Baker -12:00
Auckland +13:00
stdout
London 23:30 0 23:30 +1
Baker 11:30 0 11:30 +1
Auckland 12:30 +1 12:30 +2
3
main.py
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

The trap in this problem is folding a negative time back into one day.
In Noronha, UTC 01:10 plus the offset -02:00 gives -50 minutes, which is 23:10 on the previous day.
Python's % and // use floor division, so divmod(-50, 1440) gives (-1, 1390) directly.
In C, C++, Java, C#, JS and TS, % is the remainder of division truncated toward zero, so -50 % 1440 is -50 (Craykon's % is the same as JS).
So add 1440 and take the remainder again, as in (t % 1440 + 1440) % 1440, or in Java use Math.floorMod(t, 1440).
The day difference has the same trap.
In C, C++, Java and C#, -50 / 1440 is 0, so the previous day disappears (in JS, TS and Craykon / gives -0.0347…, so you need Math.floor).
Python // and Java Math.floorDiv give -1; in the other languages, make the division exact first, as in (t - minute of day) / 1440, then divide.
The third trap is reading the offset.
Reading "-03:30" as hours -3 and minutes +30 and adding gives -150 minutes, but the sign applies to both, so it is -210.
When the hours are 0, as in "-00:45", the sign of the hours read as an integer (-0) is lost, so it is safest to take off the sign character first and multiply by it separately.
Padding to two digits is Python f"{m:02d}", JS/TS padStart(2, "0"), Java String.format("%02d"), C# {m:D2}, C printf("%02d"), C++ std::setw(2) with std::setfill('0'), Craykon PadLeft(2, "0").

Pythonmain.py · 27 lines
def offset_minutes(s):    # "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210    sign = -1 if s[0] == "-" else 1    return sign * (int(s[1:3]) * 60 + int(s[4:6]))  def local(t):    # divmod는 내림 나눗셈이라 t가 음수여도 나머지가 0~1439, 몫이 날짜 차이(-1 등)다    day, minute = divmod(t, 1440)    tag = "+" + str(day) if day > 0 else str(day)    return f"{minute // 60:02d}:{minute % 60:02d} {tag}", day  hhmm, d = input().split()start = int(hhmm[:2]) * 60 + int(hhmm[3:])d = int(d)n = int(input())crossing = 0for _ in range(n):    name, off = input().split()    t = start + offset_minutes(off)    begin, day1 = local(t)    end, day2 = local(t + d)    print(name, begin, end)    if day1 != day2:        crossing += 1print(crossing)
JavaScriptmain.js · 27 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const DAY = 1440;// "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210const offsetMinutes = (s) => (s[0] === "-" ? -1 : 1) * (Number(s.slice(1, 3)) * 60 + Number(s.slice(4, 6)));const two = (v) => String(v).padStart(2, "0");const local = (t) => {  // JS의 %는 음수를 그대로 남긴다(-50 % 1440 === -50) → 한 번 더해서 다시 나눈다  const minute = ((t % DAY) + DAY) % DAY;  const day = (t - minute) / DAY; // 이제 딱 나누어떨어진다(내림과 같다)  return { text: `${two(Math.floor(minute / 60))}:${two(minute % 60)} ${day > 0 ? "+" + day : day}`, day };};const [hhmm, dText] = lines[0].trim().split(/\s+/);const start = Number(hhmm.slice(0, 2)) * 60 + Number(hhmm.slice(3));const d = Number(dText);const n = Number(lines[1]);const out = [];let crossing = 0;for (let i = 0; i < n; i++) {  const [name, off] = lines[2 + i].trim().split(/\s+/);  const t = start + offsetMinutes(off);  const begin = local(t);  const end = local(t + d);  out.push(`${name} ${begin.text} ${end.text}`);  if (begin.day !== end.day) crossing++;}out.push(String(crossing));console.log(out.join("\n"));
TypeScriptmain.ts · 28 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const DAY = 1440;// "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210const offsetMinutes = (s: string): number => (s[0] === "-" ? -1 : 1) * (Number(s.slice(1, 3)) * 60 + Number(s.slice(4, 6)));const two = (v: number): string => String(v).padStart(2, "0");const local = (t: number): { text: string; day: number } => {  // JS의 %는 음수를 그대로 남긴다(-50 % 1440 === -50) → 한 번 더해서 다시 나눈다  const minute = ((t % DAY) + DAY) % DAY;  const day = (t - minute) / DAY; // 이제 딱 나누어떨어진다(내림과 같다)  return { text: `${two(Math.floor(minute / 60))}:${two(minute % 60)} ${day > 0 ? "+" + day : day}`, day };};const [hhmm, dText] = lines[0].trim().split(/\s+/);const start = Number(hhmm.slice(0, 2)) * 60 + Number(hhmm.slice(3));const d = Number(dText);const n = Number(lines[1]);const out: string[] = [];let crossing = 0;for (let i = 0; i < n; i++) {  const [name, off] = lines[2 + i].trim().split(/\s+/);  const t = start + offsetMinutes(off);  const begin = local(t);  const end = local(t + d);  out.push(`${name} ${begin.text} ${end.text}`);  if (begin.day !== end.day) crossing++;}out.push(String(crossing));console.log(out.join("\n"));
JavaMain.java · 37 lines
import java.io.BufferedReader;import java.io.InputStreamReader; public class Main {    static final int DAY = 1440;     // "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210    static int offsetMinutes(String s) {        int sign = s.charAt(0) == '-' ? -1 : 1;        return sign * (Integer.parseInt(s.substring(1, 3)) * 60 + Integer.parseInt(s.substring(4, 6)));    }     static String local(int t) {        // Java의 %는 음수를 남기고 /는 0 쪽으로 버린다 → floorMod, floorDiv를 쓴다        int minute = Math.floorMod(t, DAY);        int day = Math.floorDiv(t, DAY);        return String.format("%02d:%02d %s%d", minute / 60, minute % 60, day > 0 ? "+" : "", day);    }     public static void main(String[] args) throws Exception {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        String[] first = in.readLine().trim().split("\\s+");        int start = Integer.parseInt(first[0].substring(0, 2)) * 60 + Integer.parseInt(first[0].substring(3));        int d = Integer.parseInt(first[1]);        int n = Integer.parseInt(in.readLine().trim());        StringBuilder out = new StringBuilder();        int crossing = 0;        for (int i = 0; i < n; i++) {            String[] p = in.readLine().trim().split("\\s+");            int t = start + offsetMinutes(p[1]);            out.append(p[0]).append(' ').append(local(t)).append(' ').append(local(t + d)).append('\n');            if (Math.floorDiv(t, DAY) != Math.floorDiv(t + d, DAY)) crossing++;        }        out.append(crossing).append('\n');        System.out.print(out);    }}
C#Main.cs · 44 lines
using System;using System.Text; class Program{    const int Day = 1440;     // "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210    static int OffsetMinutes(string s)    {        int sign = s[0] == '-' ? -1 : 1;        return sign * (int.Parse(s.Substring(1, 2)) * 60 + int.Parse(s.Substring(4, 2)));    }     // C#의 %는 나뉘는 수의 부호를 따른다(-50 % 1440 == -50) → 더해서 다시 나눈다    static int MinuteOfDay(int t) => (t % Day + Day) % Day;    // 날짜 차이는 내림: t - (그날의 분)은 1440으로 딱 나누어떨어진다    static int DayShift(int t) => (t - MinuteOfDay(t)) / Day;     static string Local(int t)    {        int m = MinuteOfDay(t), day = DayShift(t);        return $"{m / 60:D2}:{m % 60:D2} {(day > 0 ? "+" : "")}{day}";    }     static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int start = int.Parse(first[0].Substring(0, 2)) * 60 + int.Parse(first[0].Substring(3));        int d = int.Parse(first[1]);        int n = int.Parse(Console.ReadLine());        var sb = new StringBuilder();        int crossing = 0;        for (int i = 0; i < n; i++)        {            string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);            int t = start + OffsetMinutes(p[1]);            sb.Append(p[0]).Append(' ').Append(Local(t)).Append(' ').Append(Local(t + d)).Append('\n');            if (DayShift(t) != DayShift(t + d)) crossing++;        }        sb.Append(crossing).Append('\n');        Console.Write(sb);    }}
C++main.cpp · 36 lines
#include <iomanip>#include <iostream>#include <sstream>#include <string> constexpr int DAY = 1440; // C++의 %도 0 쪽으로 버린 나눗셈의 나머지(-50 % 1440 == -50) → 더해서 다시 나눈다int minuteOfDay(int t) { return (t % DAY + DAY) % DAY; }// 날짜 차이는 내림: t - (그날의 분)은 1440으로 딱 나누어떨어진다int dayShift(int t) { return (t - minuteOfDay(t)) / DAY; } std::string local(int t) {    int m = minuteOfDay(t), day = dayShift(t);    std::ostringstream s;    s << std::setfill('0') << std::setw(2) << m / 60 << ':' << std::setw(2) << m % 60 << ' '      << (day > 0 ? "+" : "") << day;    return s.str();} int main() {    std::string hhmm;    int d, n;    std::cin >> hhmm >> d >> n;    int start = std::stoi(hhmm.substr(0, 2)) * 60 + std::stoi(hhmm.substr(3, 2));    int crossing = 0;    for (int i = 0; i < n; i++) {        std::string name, off;        std::cin >> name >> off;        // "-03:30"의 부호는 시와 분 모두에 붙는다        int t = start + (off[0] == '-' ? -1 : 1) * (std::stoi(off.substr(1, 2)) * 60 + std::stoi(off.substr(4, 2)));        std::cout << name << ' ' << local(t) << ' ' << local(t + d) << '\n';        if (dayShift(t) != dayShift(t + d)) crossing++;    }    std::cout << crossing << '\n';}
Cmain.c · 37 lines
#include <stdio.h> #define DAY 1440 /* C의 %는 0 쪽으로 버린 나눗셈의 나머지라 음수가 나올 수 있다 → 더해서 다시 나눈다 */int minute_of_day(int t) { return (t % DAY + DAY) % DAY; } /* 날짜 차이는 내림이어야 한다: t - (그날의 분)은 1440으로 딱 나누어떨어진다 */int day_shift(int t) { return (t - minute_of_day(t)) / DAY; } void print_local(int t) {    int m = minute_of_day(t), day = day_shift(t);    printf("%02d:%02d %s%d", m / 60, m % 60, day > 0 ? "+" : "", day);} int main(void) {    int sh, sm, d, n;    scanf("%d:%d %d", &sh, &sm, &d);    scanf("%d", &n);    int start = sh * 60 + sm, crossing = 0;    for (int i = 0; i < n; i++) {        char name[32], sign;        int oh, om;        scanf("%31s %c%d:%d", name, &sign, &oh, &om);        /* "-03:30"의 부호는 시와 분 모두에 붙는다 */        int off = (sign == '-' ? -1 : 1) * (oh * 60 + om);        int t = start + off;        printf("%s ", name);        print_local(t);        printf(" ");        print_local(t + d);        printf("\n");        if (day_shift(t) != day_shift(t + d)) crossing++;    }    printf("%d\n", crossing);    return 0;}
Craykonmain.cray · 51 lines
// "-03:30"의 부호는 시와 분 모두에 붙는다: -(3 * 60 + 30) = -210차이분(s){    분 = s.Substring(1, 2).ToNumber() * 60 + s.Substring(4, 2).ToNumber();    if (s.Substring(0, 1) == "-")    {        return -분;    }    return 분;} // 크레이콘의 %도 JS처럼 음수를 남긴다(-50 % 1440 == -50) → 더해서 다시 나눈다그날의분(t){    return (t % 1440 + 1440) % 1440;} // 날짜 차이는 내림: t - (그날의 분)은 1440으로 딱 나누어떨어진다날짜차이(t){    return (t - 그날의분(t)) / 1440;} 시각(t){    m = 그날의분(t);    day = 날짜차이(t);    표 = "" + day;    if (day > 0)    {        표 = "+" + day;    }    return ("" + Mathf.Quot(m, 60)).PadLeft(2, "0") + ":" + ("" + m % 60).PadLeft(2, "0") + " " + 표;} 첫줄 = Console.ReadLine().Split();start = 첫줄[0].Substring(0, 2).ToNumber() * 60 + 첫줄[0].Substring(3, 2).ToNumber();d = 첫줄[1].ToNumber();n = Console.ReadLine().ToNumber();crossing = 0;for (i = 0; i < n; i++){    칸 = Console.ReadLine().Split();    t = start + 차이분(칸[1]);    Console.WriteLine(칸[0] + " " + 시각(t) + " " + 시각(t + d));    if (날짜차이(t) != 날짜차이(t + d))    {        crossing += 1;    }}Console.WriteLine(crossing);