日期类-省赛B组
十二届省赛B 时间显示

using namespace std;
int main()
{
long long x;
cin >> x;
long long s = x / 1000;
long long minutes = s / 60;
long long hours = minutes / 60;
printf("%02ld:%02ld:%02ld", hours % 24, minutes % 60, s % 60);
//cout << hours % 24 << ":" << minutes % 60 << ":" << s % 60;
return 0;
}
printf()
format: %[flags] [width] [.precision] [length] specifier
0,左填充0(padding)
width
2
length
l:长整型或无符号长整型
格式字符
d:十进制整数(带符号;u:十进制无符号整数),x X o 十六进制 八进制
c:字符 s:字符串 p:指针地址
f:小数形式输出单、双精度实数 e E:指数形式输出
lu llu:32 64位无符号整数
八届 日期问题
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入格式
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输入格式
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入
----02/03/04
样例输出
----2002-03-042004-02-032004-03-02
资源约定:峰值内存消耗(含虚拟机) < 256MCPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:main函数需要返回0;只使用ANSI C/ANSI C++ 标准;不要调用依赖于编译环境或操作系统的特殊函数。所有依赖的函数必须明确地在源文件中 #include <xxx>不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
排除法(考场不建议,逻辑处理太慢排序)
思路:
3种可能组合,合法性(排除法)+排序。
特别注意边缘数据处理排序。注意去重。
01/31/02
12/13/14
//scanf不安全 dismiss
using namespace std;
int year(int a)
{
if (a >= 60)
return 1900 + a;
else if(a<=59)
return 2000 + a;
}
//判断日期合法性 年月日
bool solve(int a, int b, int c)
{
if (b >= 1 && b <= 12) {
if (b == 1 || b == 3 || b == 5 || b == 7 || b == 8 || b == 10 || b == 12){
if (c >= 1 && c <= 31) {
return true;
}
return false;
}
else if (b == 2) {
if ((a % 4 == 0 and a % 100 != 0) or a % 400 == 0) {//闰年2月29天;闰年:能被4整除且不能被100整除,或能被400整除是润年。
if (c >= 1 and c <= 29) return true;
return false;
}
else {
if (c >= 1 and c <= 28) return true;
return false;
}
}
else {
if (c >= 1 and c <= 30) {
return true;
}
return false;
}
}
}
int main()
{
int a, b, c;
scanf("%d/%d/%d",&a,&b,&c); //年月日
int ra = year(a);
//int rb = year(b);
int rc = year(c);
//if (solve(ra, b, c)) {//年月日
//printf("%d-%02d-%02d\n", ra, b, c);
//}
//if (solve(rc, a, b)) { //月日年
//printf("%d-%02d-%02d\n", rc, a, b);
//}
//if (a!=b and solve(rc, b, a)) { //日月年
//printf("%d-%02d-%02d\n", rc, b, a);
// }
//去重
if (ra < rc) {
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
if (a < b) {
if (solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
if (solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
}
else {
if (a != b and solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
if (solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
}
}
else if (ra>rc) {
if (a < b) {
if (solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
if (a != b and solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
}
else {
if (a != b and solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
if (solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
}
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
}
else {//ra=rc
if (a < b) {
if (solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
if (a < c) {
if (solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
}
else {
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
if (a!=c and solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
}
}
else {
if (a < c) {
if (solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
}
else {
if (solve(ra, b, c)) {//年月日
printf("%d-%02d-%02d\n", ra, b, c);
}
if (a!=c and solve(rc, b, a)) { //日月年
printf("%d-%02d-%02d\n", rc, b, a);
}
}
if (a!=b and solve(rc, a, b)) { //月日年
printf("%d-%02d-%02d\n", rc, a, b);
}
}
}
return 0;
}
枚举法
枚举法直接从时间范围内遍历所有可能的值,先判断枚举值和输入是否一致,然后判断时间格式是否合法。这是用遍历来换取排序输出。
using namespace std;
bool isValid(int y, int m, int d) {//1967 02 03
if (m <= 12 and m >= 1) {
if (m != 2) {
if ((m == 1) or (m == 3) or (m == 5) or (m == 7) or (m == 8) or (m == 10) or (m == 12)) {
if (d >= 1 and d <= 31) return true;
}
else {
if (d >= 1 and d <= 30) return true;
}
}
else {
if ((y % 4 == 0 and y % 100 != 0) or y % 400 == 0) {
if (d >= 1 and d <= 29) return true;
}
else {
if (d >= 1 and d <= 28) return true;
}
}
}
return false;
}
int main()
{
int a, b, c;
scanf("%d/%d/%d",&a,&b,&c); //年月日
for (int i = 19600101; i <= 20591231; i++) {//用int表示年月日
int y = i/ 10000 ;//分割年月日
int m = i / 100 % 100;
int d = i % 100;
//三种选择匹配判断
if ((y % 100 == a and m == b and d== c) or
(y % 100 == c and m == b and d == a) or
(y % 100 == c and m == a and d == b)) {
if (isValid(y, m, d)) printf("%d-%02d-%02d\n",y,m,d);
}
}
return 0;
}
逻辑处理大体上是条件控制(if..else)和循环控制(while;for),所以不用惧怕。
细节处理(边缘和普通的条件处理)用if语句就好啦。
十一届 回文日期

日期+回文
思路:纯粹将回文中加了数的格式化限制(日期类型),直接添加一个日期合法化判断函数,然后在主函数中从当前日期遍历出下一个回文日期。
using namespace std;
//判断日期合法化的标准代码模板
int month_days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
bool isValid(int n) {
int y = n / 10000;
int m = n / 100 % 100;
int d = n % 100;
if (m >= 1 and m <= 12) {
if (d >= 1 and d <= month_days[m]) { return true; }
if (m==2 and ((y % 4 == 0 and y % 100 != 0) or y % 400 == 0)) {
if (d == 29) return true;
}
return false;
}
return false;
}
bool ishuiwen1(int n) {
int a = n / 10000000;
int b = n / 1000000 % 10;
int c = n / 100000 % 10;
int d = n / 10000 % 10;
int e = n / 1000 % 10;
int f = n / 100 % 10;
int g = n / 10 % 10;
int h = n % 10;
if (a == h and b == g and c == f and d == e) return true;
return false;
}
//注意a!=b,只用在回文数判断上加一个限制
bool ishuiwen2(int n) {
int a = n / 10000000;
int b = n / 1000000 % 10;
int c = n / 100000 % 10;
int d = n / 10000 % 10;
int e = n / 1000 % 10;
int f = n / 100 % 10;
int g = n / 10 % 10;
int h = n % 10;
if (a == h and b == g and c == f and d == e and a==c and b==d and a!=b) return true;
return false;
}
int main()
{
int n;
cin >> n;
int flag = 0;
for (int i = n;; i += 1) {
if (isValid(i)) {
if (ishuiwen1(i) and not flag) {//避免重复输出符合第一个回文数要求的数
cout << i << endl;
flag = 1;
}
if (ishuiwen2(i)) {//继续判断第二类回文数
cout << i << endl;
return 0;
}
}
}
}

浙公网安备 33010602011771号