题目链接
读题:
1、本题给出两个日期,要求求这两个日期范围内(包括这两个日期)的回文日期数量
关键点:
1、思路是直接枚举,不过要注意几个细节
如何处理输入:
我想的是将输入改为字符串,再根据年月日的顺序分别存开始和结束的年月日
cin>>start>>End;
int ystart=0, mstart=0, dstart=0, yend=0, mend=0, dend=0;
for (int i=0; i<4; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
ystart += x*pow(10, 3-i);
yend += y*pow(10, 3-i);
}
for (int i=4; i<6; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
mstart += x*pow(10, 5-i);
mend += y*pow(10, 5-i);
}
for (int i=6; i<8; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
dstart += x*pow(10, 7-i);
dend += y*pow(10, 7-i);
}
闰年的判断
如果
1.这个年份是4的整数倍,但不是100的整数倍;
2.这个年份是400的整数倍。
3、本月要为2月
if ((ystart%400==0)||(ystart%100!=0&&ystart%4==0))
{
if (mstart==2)
m++;
}
判断回文:
我想的是,将年月日合成一个8位整数来判断
int ans = ystart*10000+mstart*100+dstart;
int ans2 = ans;;
int sum = 0;
while (ans)
{
sum = sum*10+ans%10;
ans/=10;
}
if (ans2 == sum)
{
total++;
}
最后注意日期加一时,月年的判断
完整代码:
# include <iostream>
# include <cstring>
# include <cmath>
using namespace std;
string start, End;
int total;
int mon[20] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
cin>>start>>End;
int ystart=0, mstart=0, dstart=0, yend=0, mend=0, dend=0;
for (int i=0; i<4; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
ystart += x*pow(10, 3-i);
yend += y*pow(10, 3-i);
}
for (int i=4; i<6; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
mstart += x*pow(10, 5-i);
mend += y*pow(10, 5-i);
}
for (int i=6; i<8; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
dstart += x*pow(10, 7-i);
dend += y*pow(10, 7-i);
}
while (1)
{
int ans = ystart*10000+mstart*100+dstart;
int ans2 = ans;;
int sum = 0;
while (ans)
{
sum = sum*10+ans%10;
ans/=10;
}
if (ans2 == sum)
{
total++;
}
if (ystart == yend && mstart == mend && dstart == dend)
{
cout<<total;
break;
}
dstart++;
int m = mon[mstart];
if ((ystart%400==0)||(ystart%100!=0&&ystart%4==0))
{
if (mstart==2)
m++;
}
if (dstart>m)
{
dstart = 1;
mstart++;
if (mstart>12)
{
mstart = 1;
ystart++;
}
}
}
return 0;
}
更新:
此题有更为快速的方法,即利用构造回文数反过来的思想,可以用年构造月日,或者用月日构造年,这里用年来构造,
计算起始的年份,遍历年份,构造相应的月日,并判断这些月日是否存在
易错点:
最后一年的判断:
最后一年构造出的月日,还得不仅得判断是否存在,还得判断是否在所求范围内
完整代码:
# include <iostream>
# include <cstring>
# include <cmath>
using namespace std;
string start, End;
int cnt;
int mon[20] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
cin>>start>>End;
int ystart=0, mstart=0, dstart=0, yend=0, mend=0, dend=0;
for (int i=0; i<4; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
ystart += x*pow(10, 3-i);
yend += y*pow(10, 3-i);
}
for (int i=4; i<6; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
mstart += x*pow(10, 5-i);
mend += y*pow(10, 5-i);
}
for (int i=6; i<8; i++)
{
int x = start[i]-'0';
int y = End[i]-'0';
dstart += x*pow(10, 7-i);
dend += y*pow(10, 7-i);
}
for (int i=ystart; i<=yend; i++)
{
int sum = 0;
int tmp =i;
while (tmp)
{
sum = sum*10+tmp%10;
tmp/=10;
}
int tmpmon = sum/100;
int tmpday = sum-tmpmon*100;
int maxday = mon[tmpmon];
if (tmpmon>12)
continue;
if ((i%400==0)||((i%100!=0)&&(i%4==0)))
{
if (tmpmon==2)
maxday++;
}
if (tmpday<=maxday)
{
if (i==yend&&(tmpday<=dend&&tmpmon<=mend))
cnt++;
else if (i<yend)
cnt++;
}
}
cout<<cnt;
return 0;
}