刷题记录(枚举)--NC16438 回文日期

题目链接

读题:

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值