zoukankan      html  css  js  c++  java
  • POJ 1446

    题目大意:

    输入年、月、日、星期、小时、分钟、秒,以及所处的时区,要求将其转换成UTC+3时区内的时间。

    浑身都是坑的模拟题。

    ①题目没有说是单组还是多组数据(其他OJ上的版本是多组数据),保险起见建议处理到EOF。

    ②"Year: Set by two or four decimal digits. If a year is set by two decimals it is assumed that this is a number of the year of the XX century."

    我查了谷歌翻译才反应过来那个XX是罗马数字20……输入年份时不能直接"%d",得先读成字符串,再判断长度,如果长度为2则在转成整数时需要加上1900。

    ③"First two digits set the hours and the last two the minutes of offset value."

    在求该时区与UTC+3相差的偏移量时,不能简单粗暴地用300减去读入的数。假如输入+0130,那么300-130的结果就是170,该结果显然是错误的。

    ④"The absolute value of the difference does not exceed 24 hours."

    注意-2350这样的极端情形,加的天数有可能是2天!(虽然现实中不存在-2350这样的时区划分,但本题的数据就不好说了)

    ⑤"Your program should rely on the predefined correctness of the given Day-of-week and Time-zone."

    这句话的意思其实是说输入数据保证格式和内容都是正确的,我一开始看到这句还愣了一会儿(没见过这种操作)……

    ⑥"February, as a rule, has 28 days, save for the case of the leap year (29 days)."

    学到了一个新短语:save for(手动笑哭

    本题是需要考虑闰年的,闰年的判定法与现实一致:四年一闰,百年不闰,四百年再闰。

    ⑦"The output string should not include leading and trailing spaces."

    注意行末不能有空格。另外输出时一定要注意加前导零。

    AC代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <stdexcept>
      5 #include <string>
      6 
      7 const char dayOfWeekName[7][4] = {
      8         "SUN",
      9         "MON",
     10         "TUE",
     11         "WED",
     12         "THU",
     13         "FRI",
     14         "SAT"
     15 };
     16 const char monthName[12][4] = {
     17         "JAN",
     18         "FEB",
     19         "MAR",
     20         "APR",
     21         "MAY",
     22         "JUN",
     23         "JUL",
     24         "AUG",
     25         "SEP",
     26         "OCT",
     27         "NOV",
     28         "DEC"
     29 };
     30 const char timeZoneOffsetName[6][4] = {
     31         "UT",
     32         "GMT",
     33         "EDT",
     34         "CDT",
     35         "MDT",
     36         "PDT"
     37 };
     38 const int timeZoneOffset[6] = {0, 0, -400, -500, -600, -700};
     39 const int dayNumberOfMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //non-leap year
     40 
     41 inline bool isLeapYear(int year)
     42 {
     43     return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
     44 }
     45 
     46 inline int getMonthId(const char* month)
     47 {
     48     for (int i = 0; i < 12; i++)
     49         if (strcmp(month, monthName[i]) == 0)
     50             return i;
     51 
     52     throw std::invalid_argument("invalid month name: " + std::string(month));
     53 }
     54 
     55 inline int getDayOfWeekId(const char* dayOfWeek)
     56 {
     57     for (int i = 0; i < 7; i++)
     58         if (strcmp(dayOfWeek, dayOfWeekName[i]) == 0)
     59             return i;
     60 
     61     throw std::invalid_argument("invalid day of week: " + std::string(dayOfWeek));
     62 }
     63 
     64 int getOffset(const char* timeZone)
     65 {
     66     if (timeZone[0] == '+' || timeZone[0] == '-') //in digit form
     67         //return 300 - atoi(timeZone); //WRONG!!!
     68     {
     69         int tz = atoi(timeZone); //example: +0235
     70         if (tz > 0 && tz < 300)
     71             tz += 40; //+0235 -> 275
     72         return 300 - tz; //+0235 -> 275 -> +0025
     73     }
     74     else
     75         for (int i = 0; i < 6; i++)
     76             if (strcmp(timeZone, timeZoneOffsetName[i]) == 0)
     77                 return 300 - timeZoneOffset[i];
     78 
     79     throw std::invalid_argument("invalid time zone: " + std::string(timeZone));
     80 }
     81 
     82 int advanceClock(int& hour, int& minute, int offset)
     83 {
     84     if (offset >= 0)
     85     {
     86         minute += offset % 100;
     87         if (minute >= 60)
     88         {
     89             minute -= 60;
     90             hour += 1;
     91         }
     92         hour += offset / 100;
     93         if (hour >= 24)
     94         {
     95             int temp = hour / 24;
     96             hour %= 24;
     97             return temp;
     98         }
     99     }
    100     else //offset < 0
    101     {
    102         minute -= (-offset % 100);
    103         if (minute < 0)
    104         {
    105             minute += 60;
    106             hour -= 1;
    107         }
    108         hour -= (-offset / 100);
    109         if (hour < 0)
    110         {
    111             hour += 24;
    112             return -1;
    113         }
    114     }
    115     return 0;
    116 }
    117 
    118 void forwardDate(int& year, char* month, int& dayOfMonth, char* dayOfWeek, int offset)
    119 {
    120     int monthId = getMonthId(month); //0-based
    121     int curDayNumber = dayNumberOfMonth[monthId] + (monthId == 1 && isLeapYear(year));
    122 
    123     int dayOfWeekId = getDayOfWeekId(dayOfWeek);
    124     strcpy(dayOfWeek, dayOfWeekName[(dayOfWeekId + 1) % 7]);
    125 
    126     if ((dayOfMonth += offset) > curDayNumber)
    127     {
    128         dayOfMonth = 1;
    129         if ((monthId += 1) >= 12)
    130         {
    131             monthId = 0;
    132             year += 1;
    133         }
    134     }
    135     strcpy(month, monthName[monthId]); //maybe advanced before
    136 }
    137 
    138 void backwardDate(int& year, char* month, int& dayOfMonth, char* dayOfWeek)
    139 {
    140     int monthId = getMonthId(month); //0-based
    141 
    142     int dayOfWeekId = getDayOfWeekId(dayOfWeek);
    143     strcpy(dayOfWeek, dayOfWeekName[(dayOfWeekId + 6) % 7]);
    144 
    145     if ((dayOfMonth -= 1) <= 0)
    146     {
    147         if ((monthId -= 1) < 0)
    148         {
    149             monthId = 11;
    150             year -= 1;
    151         }
    152         dayOfMonth = dayNumberOfMonth[monthId] + (monthId == 1 && isLeapYear(year));
    153         //update dayOfMonth before monthId
    154     }
    155     strcpy(month, monthName[monthId]);
    156 }
    157 
    158 bool solve()
    159 {
    160     char dayOfWeek[5];
    161     char month[4];
    162     char timeZone[8];
    163     char yearStr[5];
    164     int dayOfMonth;
    165     int year;
    166     int hour, minute, second;
    167     int offset;
    168 
    169     if (scanf("%s%d%s%s%d:%d:%d%s", dayOfWeek, &dayOfMonth, month, yearStr,
    170               &hour, &minute, &second, timeZone) == EOF)
    171         return false;
    172 
    173     dayOfWeek[3] = ''; //erase the comma
    174     year = (strlen(yearStr) == 4 ? atoi(yearStr) : 1900 + atoi(yearStr));
    175 
    176     offset = getOffset(timeZone);
    177     int advanceClockResult = advanceClock(hour, minute, offset);
    178 
    179     if (advanceClockResult >= 1)
    180         forwardDate(year, month, dayOfMonth, dayOfWeek, advanceClockResult);
    181     else if (advanceClockResult == -1)
    182         backwardDate(year, month, dayOfMonth, dayOfWeek);
    183 
    184     printf("%s, %02d %s %04d %02d:%02d:%02d +0300",
    185            dayOfWeek, dayOfMonth, month, year, hour, minute, second);
    186 
    187     return true;
    188 }
    189 
    190 int main()
    191 {
    192     for (int i = 0; solve(); i++)
    193     {
    194         if (i > 0)
    195             putchar('
    ');
    196     }
    197     return 0;
    198 }
  • 相关阅读:
    vbscript错误代码及对应解释大全(希望还没过时)
    对象存储服务MinIO安装部署分布式及Spring Boot项目实现文件上传下载
    一道算法题,求更好的解法
    浅谈SQLite——实现与应用
    Linux网络协议栈(二)——套接字缓存(socket buffer)
    服务器开发入门——理解异步I/O
    理解MySQL——复制(Replication)
    线性时间排序算法
    Linux网络协议栈(一)——Socket入门(2)
    理解MySQL——索引与优化
  • 原文地址:https://www.cnblogs.com/Onlynagesha/p/8459975.html
Copyright © 2011-2022 走看看