实验七 数组(二)---小希的新工作
0、题目概述
【问题描述】
给定 n (1 ≤ n ≤ 24)个正整数a1、a2、…、an,请判断这 n 个数是否是连续 n 个月份的天数,这些月份可以跨年度。
【输入形式】
输入第一行为一个整数 n,第二行为n个正整数 a1、a2、…、an(28 ≤ ai ≤ 31)。
【输出形式】
输出Yes或No。
【样例输入1】
4
31 31 30 31
【样例输出1】
Yes
【样例输入2】
2
30 30
【样例输出2】
No
【样例输入3】
5
29 31 30 31 30
【样例输出3】
Yes
【样例说明】
在第一个样例中,连续4个数是7、8、9、10月份的天数
在第二个样例中,没有哪两个连续月份的天数都为30
在第三个样例中,是某闰年的2、3、4、5、6月份的天数
【评分标准】
1、分析
这一题的难点是烦,最多24个月。如果真的有空,可以考虑把所有的情况都列出来依次比较,这样复杂度貌似是o(1)
2、解决方案
情况分类:
我采取的是数组的形式,因为24个月(两年)只有两种情况,一种是双平年,一种是一平年一闰年。注意:先润后平和先平后润是一样的。
如何比较:
- 对两个数组都进行判断,只要有一个成立就可以.
- 对数组内的月份一次遍历,从第一个月开始比较,如果相同则比较下一个月,如果不同,则第一个月向后移。比如题给数据是 六七八 月。则先将题给六月与数组一月对比,如果不同则依次与二月、三月…比较。六月相同七月不同则同理,类似于比较字符串。
- 注意年末12月的后一个月是1月,要及时调整指针指向。
3、代码
#include <iostream>为避免学校oj系统查重抄袭,所有变量在使用时请进行修改
using namespace std;
int NNNNN;//定义一个全局变量n,用来记录有几个月,我只是单纯的不想多传值
int JUD(int month[],int sta[]) {//判断月份是否相符
int num=0,a;
while (num<24) {
bool bo=true;//相符的判断标志符,先假设当前比较的会成立
a=0;
for (int i=0; i<NNNNN; i++) {
if (num+a>23) a=num+a-24-num;//年末12月的下一个月是1月
//这里将指针的值指回一月
if (sta[num+a]!=month[i]) {//如果不同则不成立
bo=false;
break;
}
a++;
}
if (bo==true) {//找到成立的序列,立即结束
return 1;
}
num++;
}
cout<<endl;
return 0;
}
int main() {
cin>>NNNNN;
int month[NNNNN];
int arr1[24]= {31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31};
int arr2[24]= {31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31};
//定义月份
for (int i=0; i<NNNNN; i++) {
cin>>month[i];
}//读入
if ((JUD(month,arr1)==1)||(JUD(month,arr2)==1)) cout<<"Yes";//判断
else cout<<"No";
return 0;
}
4、总结
这道题没有什么评价,难点是月份指回一月。
我所能想到的最简方案有两种,但是本质是一样的:
方案一
用字符串读入月份,并定义所有情况(24个月)的比较字符串。如果能再定义的字符串的字串中找到题给输入,则成立。
方案二
用数组读入月份,定义两个数组(闰闰&&平闰),利用< algorithm >库中的find函数,找到当前月份的出现地址,如果读入n个月的出现地址是相连的,则成立