C++循环综合例题(1)
例题:洛谷B3737双十一
题目描述:
每年
11
11
11 月
11
11
11 日,各大网上商店都会有促销活动,因此大家都希望
11
11
11 月
11
11
11 日在周末,就可以更愉快地购物啦。请你写一个程序计算一段时间中,
11
11
11 月
11
11
11 日是周末(周六或周日)的数量。以下关于日期的定义和事实能帮到你:
- 1900 1900 1900 年 1 1 1 月 1 1 1 日是星期一
- 每年的 1 , 3 , 5 , 7 , 8 , 10 , 12 1,3,5,7,8,10,12 1,3,5,7,8,10,12 月有 31 31 31 天; 4 , 6 , 9 , 11 4,6,9,11 4,6,9,11 月有 30 30 30 天;闰年的 2 2 2 月有 29 29 29 天,非闰年的 2 2 2 月有 28 28 28 天。
- 闰年的计算方法:不能被 100 100 100 整除的年份称为普通年。普通年能被 4 4 4 整除的为闰年,因此 2004 2004 2004 年是闰年, 1999 1999 1999 年不是闰年;能被 100 100 100 年整除的年份称为世纪年。世纪年能被 400 400 400 整除的是闰年,因此 2000 2000 2000 年是闰年, 1900 1900 1900 年不是闰年。
输入格式:
输入一行两个整数 x , y x,y x,y ,代表需要计算的起止年份。
输出格式:
输出一个整数,第 x x x 年到第 y y y 年中 11 11 11 月 11 11 11 日是周末的年数(包括第 x x x 年和第 y y y 年)
输入样例:
2018 2100
输出样例:
23
数据范围:
1900
<
=
x
<
=
y
<
=
3000
1900<=x<=y<=3000
1900<=x<=y<=3000
分析
本题的题意是要求输出在第 x x x 年和第 y y y 年范围内的 11 11 11 月 11 11 11 日是周末的数量
那么有人可能会说:只要把第一个 11 11 11 月 11 11 11 日是星期几算出来,后面的都可以推出来了?
但是,闰年的问题仍然无法避免
所以我们可以先用循环算出第一年的双十一是星期几,然后再判断下一年是否是闰年,将对应天数除以一个星期七天,算出下一年的双十一是星期几即可。
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int x,y;
cin>>x>>y;
int day=1,mon=1,date=1;
for(int i=2;i<=365;i++)
{
date++;
day++;
if(day==8)
{
day=1;
}
if((mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)&&date>31)//月份进位
{
date=1;
mon++;
}
else if(mon==2&&date>28)
{
mon++;
date=1;
}
else if(date>30&&(mon==4||mon==6||mon==9||mon==11))
{
mon++;
date=1;
}
if(mon==11&&date==11)
{
break;
}
}//以上代码是找1900年11月11日是星期几,自己的代码可以直接写星期日,缩减代码长度
int ans=0;
if(x<=1900)
{
ans++;
}
for(int i=1901;i<=y;i++)
{
int sum=365;
if(i%4==0&&i%100!=0 || i%400==0)//判断是否为闰年
{
sum=366;
}
day+=sum%7;//加上空余天数
if(day>7)
{
day-=7;//减去可能的多余
}
if(i>=x&&(day==6||day==7))//判断
{
ans++;
}
}
cout<<ans;
return 0;
}
当然,这种代码可能需要一定的调试才能顺利通过数据,甚至可能控制不当还会出现反例
那么为了保证代码准确性,在考试时,我们可以采取穷举的算法
遍历一遍从 1900 1900 1900 年到 y y y 年的所有日子,判断即可
穷举算法:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int x,y;
cin>>x>>y;
int date=1,day=1,mon=1,year=1900;
int ans=0;
while(y>=year)
{
date++;
day++;
if(day==8)
{
day=1;
}
int sum=365;
if(year%4==0&&year%100!=0 ||(year%400==0))
{
sum=366;
}
if((mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)&&date>31)//月份进位
{
date=1;
mon++;
}
if(mon==2)
{
if(sum==365&&date>28)
{
date=1;
mon++;
}
if(sum==366&&date>29)
{
date=1;
mon++;
}
}
if(date>30&&(mon==4||mon==6||mon==9||mon==11))
{
mon++;
date=1;
}
if(mon==11&&date==11&&(day==6||day==7)&&year>=x)
{
ans++;
}
if(mon==13)
{
mon=1;
year++;
}
}
cout<<ans;
return 0;
}