1.日期差值
思路
分别计算从第一年到两个日期过了多少天,然后相减
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int x1, x2;
int f(int year, int month, int day){
int res = 0;
for(int y = 1; y < year; y++){
if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[1] = 29;
else a[1] = 28;
for(int m = 1; m <= 12; m++){
res += a[m - 1];
}
}
if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) a[1] = 29;
else a[1] = 28;
for(int m = 1; m < month; m++){
res += a[m - 1];
}
res += day;
return res;
}
int main(){
while(cin>>x1>>x2){
int year1 = 0, month1 = 0, day1 = 0, year2 = 0, month2 = 0, day2 = 0;
for(int i = 0; i < 2; i++){
day1 = day1 + x1 % 10 * pow(10, i);
day2 = day2 + x2 % 10 * pow(10, i);
x1 /= 10, x2 /= 10;
}
for(int i = 0; i < 2; i++){
month1 = month1 + x1 % 10 * pow(10, i);
month2 = month2 + x2 % 10 * pow(10, i);
x1 /= 10, x2 /= 10;
}
for(int i = 0; i < 4; i++){
year1 = year1 + x1 % 10 * pow(10, i);
year2 = year2 + x2 % 10 * pow(10, i);
x1 /= 10, x2 /= 10;
}
//cout<<year1<<" "<<month1<<" "<<day1<<endl;
int res1 = f(year1, month1, day1);
int res2 = f(year2, month2, day2);
cout<<abs(res1 - res2) + 1<<endl;
}
return 0;
}
// 或者简化
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int x1, x2;
int f(int year, int month, int day){
int res = 0;
for(int y = 1; y < year; y++){
if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[1] = 29;
else a[1] = 28;
for(int m = 1; m <= 12; m++){
res += a[m - 1];
}
}
if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) a[1] = 29;
else a[1] = 28;
for(int m = 1; m < month; m++){
res += a[m - 1];
}
res += day;
return res;
}
int main(){
int year1, month1, day1, year2, month2, day2;
while(scanf("%04d%02d%02d", &year1, &month1, &day1) != -1){
scanf("%04d%02d%02d", &year2, &month2, &day2);
//cout<<year1<<" "<<month1<<" "<<day1<<endl;
int res1 = f(year1, month1, day1);
int res2 = f(year2, month2, day2);
cout<<abs(res1 - res2) + 1<<endl;
}
return 0;
}
// 最简化
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int f1(int year){
return (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0));
}
int f2(int year, int month){
if(month == 2) return 28 + f1(year);
else return a[month];
}
int f3(int year, int month, int day){
int res = 0;
for(int i = 1; i < year; i++) res += 365 + f1(i);
for(int i = 1; i < month; i++) res += f2(year, i);
res += day;
return res;
}
int main(){
int year1, month1, day1, year2, month2, day2;
while(scanf("%04d%02d%02d", &year1, &month1, &day1) != -1){
scanf("%04d%02d%02d", &year2, &month2, &day2);
int res1 = f3(year1, month1, day1);
int res2 = f3(year2, month2, day2);
cout<<abs(res1 - res2) + 1<<endl;
}
return 0;
}
2.日期问题
思路
按顺序枚举年月日,判断每一种情况
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check(int year, int month, int day){
if(month == 0 || month > 12) return 0;
if(day == 0) return 0;
if(month == 2){
int x = year % 400 == 0 || (year % 4 == 0 && year % 100);
if(day > a[month] + x) return 0;
}else{
if(day > a[month]) return 0;
}
return 1;
}
int main(){
int a, b, c;
scanf("%2d/%2d/%2d", &a, &b, &c);
int year, month, day;
for(int i = 19600101; i <= 20591231; i++){
year = i / 10000, month = i % 10000 / 100, day = i % 100;
if(check(year, month, day)){
if((year % 100 == a && month == b && day == c) || //年月日
(month == a && day == b && year % 100 == c) || //月日年
(day == a && month == b && year % 100 == c)){ //日月年
// 前导补 0
printf("%d-%02d-%02d\n", year, month, day);
}
}
}
return 0;
}
3.回文日期
思路
1.枚举每年每月每日,超时
2.因为回文串对称,所以只需要枚举前四位,判断符不符合
// 超时
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check1(int year, int month, int day){
if(month == 0 || month > 12) return 0;
if(day == 0) return 0;
if(month == 2){
int x = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
if(day > a[month] + x) return 0;
}else{
if(day > a[month]) return 0;
}
return 1;
}
int check2(int x){
string s = to_string(x);
for(int i = 0, j = s.size() - 1; i < j; i++, j--){
if(s[i] != s[j]) return 0;
}
return 1;
}
int main(){
int a, b;
scanf("%d%d", &a, &b);
int cnt = 0;
for(int i = a; i <= b; i++){
int year = i / 10000, month = i % 10000 / 100, day = i % 100;
if(check1(year, month, day) && check2(i)) cnt++;
}
printf("%d", cnt);
return 0;
}
// 用点脑子
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int date1, date2;
int check1(int year, int month, int day){
if(month == 0 || month > 12) return 0;
if(day == 0) return 0;
if(month == 2){
int x = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
if(day > a[month] + x) return 0;
}else{
if(day > a[month]) return 0;
}
return 1;
}
int check2(int x){
if(x >= date1 && x <= date2) return 1;
else return 0;
}
int main(){
scanf("%d%d", &date1, &date2);
int cnt = 0;
int year, month, day;
for(int i = 1000; i <= 9999; i++){
int t = i, x = 0;
for(int i = 0; i < 4; i++){
x = x * 10 + t % 10;
t /= 10;
}
year = i, month = x / 100, day = x % 100;
if(check1(year, month, day) && check2(i * 10000 + x)) cnt++;
}
printf("%d", cnt);
return 0;
}
4.日期计算
思路
累减每个月的天数,直到不够
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main(){
int y, d;
cin>>y>>d;
if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[2] = 29;
int cnt = 1;
while(d > a[cnt]){
d -= a[cnt];
cnt++;
}
cout<<cnt<<endl;
cout<<d;
return 0;
}
5.回文日期
思路
先判断回文,再判断 AB 型
#include<iostream>
#include<cstdio>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool f1(int y){
return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}
int f2(int y, int m){
if(m == 2 && f1(y)) return 29;
return a[m];
}
int main()
{
int year, month, day;
scanf("%04d%02d%02d", &year, &month, &day);
bool flag = false;
//每年只有一个回文日期 枚举年份
for(int i = year; ; i++){
//构造回文日期
int x = i, res = 0;
while(x){
res = res * 10 + x % 10;
x /= 10;
}
res += i * 10000;
//判断合法性
if(i == year && res <= year * 10000 + month * 100 + day) continue;
int m = res % 10000 / 100, d = res % 100;
if(m >= 1 && m <= 12 && d >= 1 && d <= f2(i, m)){
if(!flag)
{
printf("%04d%02d%02d\n", i, m, d);
flag = true;
}
if(m == d && d % 10 != d / 10)
{
printf("%04d%02d%02d\n", i, m, d);
break;
}
}
}
}