博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1446 - Moscow Time - 模拟
阅读量:4316 次
发布时间:2019-06-06

本文共 6462 字,大约阅读时间需要 21 分钟。

题目大意:

输入年、月、日、星期、小时、分钟、秒,以及所处的时区,要求将其转换成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 
2 #include
3 #include
4 #include
5 #include
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 < 0101 {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-based121 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 before136 }137 138 void backwardDate(int& year, char* month, int& dayOfMonth, char* dayOfWeek)139 {140 int monthId = getMonthId(month); //0-based141 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 monthId154 }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] = '\0'; //erase the comma174 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('\n');196 }197 return 0;198 }

 

转载于:https://www.cnblogs.com/Onlynagesha/p/8459975.html

你可能感兴趣的文章
Linux下获取本机IP地址的代码
查看>>
(C#)调用Webservice,提示远程服务器返回错误(500)内部服务器错误
查看>>
flex布局
查看>>
python-----python的文件操作
查看>>
java Graphics2d消除锯齿,使字体平滑显示
查看>>
控件中添加的成员变量value和control的区别
查看>>
Spring Boot Docker 实战
查看>>
Div Vertical Menu ver3
查看>>
Git简明操作
查看>>
InnoDB为什么要使用auto_Increment
查看>>
HDU 1087 Super Jumping! Jumping! Jumping!
查看>>
0007_初始模块和字节码
查看>>
[效率提升]如何管理好你的电脑文件
查看>>
C++实验二
查看>>
零零碎碎的知识
查看>>
文件转码重写到其他文件
查看>>
AC自动机模板
查看>>
python 基本语法
查看>>
git配置
查看>>
【hexo】01安装
查看>>