题目

{% fold 点击显/隐题目 %}

Last month, xiaodao together with her friend poteko took a flight from San Francisco to Shanghai. When they were driving to the airport, xiaodao suddenly realized that the clock time on potekos car is one hour faster than the clock time on her mobile phone. And both of them might be correct, but how can it be? Because that day was Nov 6th, the Daylight saving time switch day this year. Daylight saving time (DST) or summer time is the practice of advancing clocks during summer months by one hour so that evening daylight lasts an hour longer. It is arguable that using DST can reduce overall energy consumption. Not all of us are using DST now, and for those regions adopting DST, the practices are also different. In the case of California, effective in the U.S. in 2007 as a result of the Energy Policy Act of 2005, the local time changes from Pacific Standard Time (PST) to Pacific Daylight Time (PDT) at 02:00 to 03:00 on the second Sunday in March and the local time changes back from PDT to PST at 02:00 to 01:00 on the first Sunday in November. Because it is one hour longer on that day, so xiaodao and poteko didn’t miss the flights, but they found it still a little confusing. Interestingly, once xiaodao went back to Shanghai, she met a bug caused by exactly the same issue during the work. You might also be in trouble with DST some day, so here comes this problem and hope it will be helpful. The local time in California without specifying whether it is PST or PDT could be ambiguous in some cases (e.g. 2016-11-06 01:25:00). In this problem, you are given a local time in California. Check whether it is “PST”, “PDT”, “Both” or “Neither”.
The first line of the input gives the number of test cases, T. T test cases follow. Each test case consists of one line, a date string written in the following format: YYYY-MM-DD HH:MM:SS.
For each test case, first output one line containing “Case #x: ”, where x is the test case number (starting from 1), following a result string which in one of “PST”, “PDT”, “Both” or “Neither”. $\bullet$ 1 ≤ T ≤ 1000. $\bullet$ date will be legal and between “2007-01-01 00:00:00” and “2100-12-31 23:59:59”.
4 2016-03-13 01:59:59 2016-03-13 02:00:00 2016-11-06 00:59:59 2016-11-06 01:00:00
Case #1: PST Case #2: Neither Case #3: PDT Case #4: Both
{% endfold %}

题解

给你一个时间,判断该时间的描述方式(夏令时、正常时间)
由于夏令时变换牵扯到小时的变换,中间会有2个小时处于特殊情况

夏令时规则如下:

  • 3月的第二个周日的2点直接跳到3点,进入夏令时(DST)
  • 11月的第一个周日的2点跳到1点,进入太平洋标准时间(PST)

可以看出3月第二个周日的2点到3点的时间段,既不属于夏令时,也不属于大平洋标准时间(neither)
而11月第一个周日的1点到2点时间段,既有可能是夏令时,也有可能是太平洋标准时间(Both)

题目分为两步,判断任意一天是第几周的星期几;按照要求判断时间的状态

{% note danger %}
坑点
3月第二个周日的2点是Neither,3点是Neither.
11月的第一个周日的1点是Both,2点是PST.
{% endnote %}

代码

{% fold 点击显/隐代码 %}```cpp Daylight Saving Time https://github.com/OhYee/sourcecode/tree/master/ACM 代码备份
#include
#include
using namespace std;

const int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int sunday[105][15][35];
void Sunday() {
memset(sunday, 0, sizeof(sunday));
int year = 2007;
int month = 1;
int day = 7;
int cnt = 0;
while (year <= 2100) {
sunday[year - 2000][month][day] = ++cnt;
// printf("%4d-%2d-%2d %d\n", year, month, day,
// sunday[year - 2000][month][day]);
day += 7;

    if ((((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) &&
        month == 2) {
        if ((day > 29)) {
            day -= days[month++] + 1;
            cnt = 0;
        }
    } else {
        if (day > days[month]) {
            day -= days[month++];
            cnt = 0;
        }
    }

    if (month == 13) {
        month = 1;
        ++year;
    }
}

}

// 1pst,2neiter,3pdt,4both
int judge(int month, int hour, int week, bool sun, int minute, int second) {
if (month < 3) {
return 1;
} else if (month == 3) {
if (week < 2) {
return 1;
} else if (week == 2) {
if (!sun) {
return 1;
} else {
if (hour < 2) {
return 1;
} else if (hour == 2) {
return 2;
} else {
if (minute == 0 && hour == 0) {
return 2;
} else {
return 3;
}
}
}
} else {
return 3;
}
} else {
if (month < 11) {
return 3;
} else if (month == 11) {
if (week == 1) {
if (!sun) {
return 3;
} else {
if (hour < 1) {
return 3;
} else if (hour == 1) {
return 4;
} else {
return 1;
}
}
} else {
return 1;
}
} else {
return 1;
}
}
}
int main() {
Sunday();
int kase = 0;

int T;
scanf("%d", &T);
while (T--) {
    int year, month, day, hour, minute, second;
    scanf("%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute,
          &second);
    year -= 2000;
    bool sun = sunday[year][month][day] != 0;
    int week = 4;

    if (sun) {
        week = sunday[year][month][day];
    } else {
        for (int i = 1; i < 5; ++i) {
            if (day - 7 * i <= 0) {
                week = i;
                break;
            }
        }
        // for (int i = day; i < day + 7; ++i) {
        //     if (sunday[year][month][day] != 0) {
        //         week = sunday[year][month][day];
        //         break;
        //     }
        // }
    }

    // printf("%d %d\n", sun, week);

    printf("Case #%d: ", ++kase);
    int ans = judge(month, hour, week, sun, minute, second);
    if (ans == 1) {
        printf("PST\n");
    } else if (ans == 2) {
        printf("Neither\n");
    } else if (ans == 3) {
        printf("PDT\n");
    } else if (ans == 4) {
        printf("Both\n");
    }
}

return 0;

}

{% endfold %}