第一行输入
位整数
,表示起始日期。
第二行输入
位整数
,表示终止日期。
输出一个整数,表示
区间内回文日期的数量。
20110101 20111231
1
在这个样例中,在
和
之间,回文日期有
个,即
。
20000101 20101231
2
在这个样例中,在
和
之间,回文日期有
个,即
和
。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt(); // 起始日期
int b = scanner.nextInt(); // 终止日期
scanner.close();
int count = 0;
// 遍历所有可能的回文日期
// 8位回文日期的特点:前4位与后4位对称,如20211202
// 因此只需遍历前4位,后4位由前4位反转得到
int startYear = a / 10000;
int endYear = b / 10000;
for (int year = startYear; year <= endYear; year++) {
// 生成回文日期
int palindromeDate = generatePalindromeDate(year);
// 检查是否在区间内
if (palindromeDate >= a && palindromeDate <= b) {
// 检查日期是否合法
if (isValidDate(palindromeDate)) {
count++;
}
}
}
System.out.println(count);
}
/**
* 根据年份生成可能的回文日期
* 例如:年份2021,生成回文日期20211202
*/
private static int generatePalindromeDate(int year) {
// 将年份转为字符串
String yearStr = String.format("%04d", year);
// 反转年份字符串得到日期部分
String reversedYear = new StringBuilder(yearStr).reverse().toString();
// 组合成8位回文日期
return Integer.parseInt(yearStr + reversedYear);
}
/**
* 检查日期是否合法
*/
private static boolean isValidDate(int date) {
// 解析年、月、日
int year = date / 10000;
int month = (date % 10000) / 100;
int day = date % 100;
// 检查月份合法性
if (month < 1 || month > 12) {
return false;
}
// 检查日期合法性
if (day < 1) {
return false;
}
// 大月有31天
if (month == 1 || month == 3 || month == 5 || month == 7
|| month == 8 || month == 10 || month == 12) {
return day <= 31;
}
// 小月有30天
else if (month == 4 || month == 6 || month == 9 || month == 11) {
return day <= 30;
}
// 2月,考虑闰年
else { // month == 2
if (isLeapYear(year)) {
return day <= 29;
} else {
return day <= 28;
}
}
}
/**
* 判断是否为闰年
* 能被4整除但不能被100整除,或能被400整除的年份是闰年
*/
private static boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
}
代码中要加上下面这个才能运行成功,否则顺序遍历日期的这种方***超时。
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool iss(string s) {
string c = s;
reverse(c.begin(), c.end());
return s == c;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
string a, b;
cin >> a >> b;
int c = 0;
vector<int> mpa(13);
int ya = stoi(a.substr(0, 4));
int ma = stoi(a.substr(4, 2));
int da = stoi(a.substr(6, 2));
int yb = stoi(b.substr(0, 4));
int mb = stoi(b.substr(4, 2));
int db = stoi(b.substr(6, 2));
int fm = 0, fd = 0, endm = 0, endd;
int m, d;
for (int y = ya; y <= yb; y++) {
if ((y % 4 == 0 && y % 100 != 0 ) || y % 400 == 0) {
mpa = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
} else {
mpa = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
}
if (fm == 0) {
m = ma;
fm = 1;
} else {
m = 1;
}
if (y == yb) endm = mb;
else endm = 12;
for (; m <= endm; m++) {
if (fd == 0) {
d = da;
fd = 1;
} else {
d = 1;
}
for (; d <= mpa[m]; d++) {
string ys = to_string(y);
ys = string(4 - ys.size(), '0') + ys;
string ms = m < 10 ? "0" + to_string(m) : to_string(m);
string ds = d < 10 ? "0" + to_string(d) : to_string(d);
if (iss(ys + ms + ds)) {
c++;
}
}
}
}
cout << c;
}
//纯暴力枚举
//能通过 但是时间卡在1000ms徘徊 有概率会超时
#include <iostream>
using namespace std;
#include<string>
#include<vector>
#include<iomanip>
vector<int>v_mouthday,v_mouthday_runnian;
bool Is_huiwenS(string s1){
string s2;
for(int i=s1.size()-1;i>=0;i--){
s2+=s1[i];
}
if(s1==s2){
return true;
}
else{
return false;
}
}
bool Is_runnian(int y){
if(y%400==0||y%100!=0&&y%4==0){
return 1;
}
else{
return 0;
}
}
string int_to_string(int y,int m,int d){
string s;
string yyyy,mm,dd;
yyyy=to_string(y);
if(m<=9){
mm+="0";
mm+=to_string(m);
}
else{
mm=to_string(m);
}
if(d<=9){
dd+="0";
dd+=to_string(d);
}
else{
dd=to_string(d);
}
s+=yyyy;
s+=mm;
s+=dd;
return s;
}
string addoneday(string s){
string yyyy,mm,dd;
for(int i=0;i<4;i++){
yyyy+=s[i];
}
for(int i=4;i<6;i++){
mm+=s[i];
}
for(int i=6;i<8;i++){
dd+=s[i];
}
int y,d,m;
y=stoi(yyyy);
m=stoi(mm);
d=stoi(dd);
if(!Is_runnian(y)){
if(d<v_mouthday[m-1]){
d++;
}
else{
d=1;
if(m!=12){
m++;
}
else{
m=1;
y++;
}
}
}
else{
if(d<v_mouthday_runnian[m-1]){
d++;
}
else{
d=1;
if(m!=12){
m++;
}
else{
m=1;
y++;
}
}
}
return int_to_string(y,m,d);
}
int main() {
v_mouthday={31,28,31,30,31,30,31,31,30,31,30,31};
v_mouthday_runnian={31,29,31,30,31,30,31,31,30,31,30,31};
string s_begin,s_end;
cin>>s_begin>>s_end;
int sum=0;
string s=s_begin;
string s_END=addoneday(s_end);
while(s!=s_END){
if(Is_huiwenS(s)){
sum++;
s=addoneday(s);
}
else{
s=addoneday(s);
}
}
cout<<sum;
}
// 64 位输出请用 printf("%lld") #include <stdio.h>
#include <stdlib.h>
typedef struct{
int year;
int month;
int day;
int max_day;//最大日期
}date;
//初始化并判断天数
void InitMonth (date* L){
for(int i = 0;i < 12;i++){
int m = L->month;
if (m == 4 || m == 6 || m == 9 || m == 11){
L->max_day = 30;//小月
} else if (m == 02){
if ((L->year%4 == 0 && L->year%100 != 0) || (L->year%400 == 0)){
L->max_day = 29;//闰月
} else {
L->max_day = 28;//平月
}
} else {
L->max_day = 31;//大月
}
}
}
//将八位数转换为日期
void Date (int num, date* L){
L->year = num / 10000;
int rem = num % 10000;
L->month = rem / 100;
L->day = rem % 100;
}
//遍历日期
void NextDay(date* L) {
L->day++;
InitMonth(L);
if (L->day > L->max_day){
L->day = 1;
L->month++;
if (L->month >12){
L->month = 1;
L->year++;
}
}
}
//判断八位数上的数字是否对应,如20111102->2,0,1,1 ,1,1 ,0,2
int If_HuiwenDate (date L){
int Y1 = L.year/1000;
int Y2 = (L.year/100)%10;
int Y3 = (L.year/10)%10;
int Y4 = L.year%10;
int M1 = L.month/10;
int M2 = L.month%10;
int D1 = L.day/10;
int D2 = L.day%10;
return (Y1 == D2) && (Y2 == D1) && (Y3 == M2) && (Y4 == M1);
}
//判断遍历时有没有超过终止日期
int Equal (date a, date b){
if (a.year < b.year) return 1;
if (a.year > b.year) return 0;
if (a.month < b.month) return 1;
if (a.month < b.month) return 0;
return (a.day <= b.day);
}
int main() {
int start, stop;
scanf("%d",&start);
scanf("%d",&stop);
date s1, s2;
Date (start, &s1);
Date (stop, &s2);
InitMonth(&s1);
InitMonth(&s2);
date s_final = s1;
int count = 0;
while (Equal(s_final, s2)){
if(If_HuiwenDate(s_final)){
count++;
}
NextDay(&s_final);
}
printf("%d", count);
return 0;
} c++萌新写出来的暴力解法,还请各位dalao多多包涵
#include <iostream>
using namespace std;
int main() {
int begin, end;
cin >> begin >> end;
// 分离起始年月日
int y1 = begin / 10000;
int m1 = begin / 100 % 100;
int d1 = begin % 100;
int y2 = end / 10000;
int m2 = end / 100 % 100;
int d2 = end % 100;
int count = 0;
// 遍历年数,生成回文日期
for(int yy = y1;yy <= y2;yy++) {
int mm = yy % 10 * 10 + yy / 10 % 10;
int dd = yy / 100 % 10 * 10 + yy / 1000;
// 判断日期是否合法
if((yy == y1 && mm < m1) || (yy == y2 && mm > y2) || mm < 1 || mm > 12 || (yy == y1 && mm == m1 && dd < d1) || (yy == y2 && mm == m2 && dd > d2) || dd < 1 || dd > 31 ||(mm == 4 && dd > 30)||(mm == 6 && dd > 30)||(mm == 9 && dd > 30)||(mm == 11 && dd > 30) || (mm == 2 && dd > 29) || (mm == 2 && !(yy % 400 == 0 || yy % 4 == 0 && yy % 100 != 0) && dd > 28)) {
continue;
}
count++;
}
cout << count << endl;
}