C++上机_日期问题
1.求下一天的年月日
问题
已知某天的年月日,求下一天的年月日。
思路
参数:年,月,日(int)
返回值:void
处理:根据参数所给年月日,求下一天的年月日
思路:
1、定义一个数组,存储月份和天数的对应关系
2、处理闰年:(因为是不是闰年会影响二月份的天数)
再封装一个函数判断是否某年是闰年(可被4整除但不能被400整除或可被100整除)
若是闰年,2月份有29日
若不是闰年:2月份有28日
3.day++; 但如果day>当月天数,day=1,month++;
再判断是否month>12,是则让month=1,year++
代码:
#include<iostream>
using namespace std;
bool isLeap(int month);
void NextDay(int& year,int& month,int& day){
//用一个数组存储月份和天数的对应关系
int dayOfMonth[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//判断是否为闰年(会影响二月的天数)
if(isLeap(year)){
dayOfMonth[2]=29;
}else{
dayOfMonth[2]=28;
}
day++;
if(day>dayOfMonth[month]){
day=1;
month++;
}
if(month>12){
month=1;
year++;
}
}
/*
返回值:bool
参数:int year
处理:判断是否为闰年,返回对应的bool
*/
bool isLeap(int year){
if(year%400==0||year%4==0&&year%100!=0){
return true;
}
return false;
}
int main(){
//年,月,日
int year=1900;
int month=2;
int day=28;
printf("今天是%d年%d月%d日\n",year,month,day);
//调用NextDay
NextDay(year,month,day);
printf("明天是%d年%d月%d日\n",year,month,day);
return 0;
}
结果:
1.测试1900年2月28日输出:
今天是1900年2月28日
明天是1900年3月1日
2.测试2020年2月28日输出:
今天是2020年2月28日
明天是2020年2月29日
如若能够与以上结果输出一致,则表面代码没问题。
2.今年的第几天
对应的试题链接: 打印日期_牛客题霸_牛客网
题目:
输入年、月、日,计算该天是本年的第几天。
输出描述:
包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。
输出描述:
输入可能有多组测试数据,对于每一组测试数据, 输出一个整数,代表Input中的年、月、日对应本年的第几天。
示例:
输入: 1990 9 20 2000 5 1 输出: 263 122
代码
#include<iostream>
using namespace std;
int main(){
//输入年月日
int year,month,day;
while(scanf("%d%d%d\n",&year,&month,&day)!=EOF){
//定义该年第一天的年,月
int curMonth=1;
int curDay=1;
//用来统计结果
int count=1;
while(1){
if(curMonth==month&&curDay==day){
break;
}
//下一天
NextDay(year,curMonth,curDay);
count++;
}
printf("%d\n",count);
}
}
结果:
3.打印日期
链接: 打印日期_牛客题霸_牛客网
题目:
给出年分m和一年中的第n天,算出第n天是几月几号
输入描述:
输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。
输出描述:
可能有多组测试数据,对于每组数据, 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。
输入: 2000 3 2000 31 2000 40 2000 60 2000 61 2001 60 输出: 2000-01-03 2000-01-31 2000-02-09 2000-02-29 2000-03-01 2001-03-01
此题主要考察我们规范化的输入输出函数。
int main() {
//输入年份和第n天
int year, n;
while (scanf("%d%d\n", &year, &n) != EOF) {
//定义该年第一天的年,月
int curMonth = 1;
int curDay = 1;
//用来统计结果
for (int i = 1; i < n; i++) {
NextDay(year, curMonth, curDay);
}
printf("%04d-%02d-%02d\n", year, curMonth, curDay);
}
}
对于上面的代码我们进行分析:
1.由于题目要求我们的输出格式为:2000-01-03
所以我们使用了printf("%04d-%02d-%02d\n", year, curMonth, curDay);
其中4表示数据的最小输出宽度为4,写04则表示若输出不足4位,则前面用0补充。
2.接着我们来讨论,要找到第n天,为什么for循环是for(int i = 1; i < n; i++)? ===》因为第一天指的是当天,所以i初始为1,而若要求第2天时,即n=2,这样nextDay会执行1次,也就是第二天了。
故for循环为:(int i=1;i<n;i++)
3.要学习上面是实现多组数据的输入的。即:
while(scanf("%d%d\n", &year, &n) != EOF)
结果:
4.日期累加
链接:日期累加_牛客题霸_牛客网
描述
设计一个程序能计算一个日期加上若干天后是什么日期。
输入描述:
输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。
输出描述:
输出m行,每行按yyyy-mm-dd的个数输出。
示例:
输入: 1 2008 2 3 100 输出: 2008-05-13
代码
输入:
样例个数 count
日期 year month day n
处理:这个日期加上n天之后是什么样子,
例如今天是1号,3天后,n=3,三天后应该是4号,即nextday要被执行3次,
故for循环应设计为:
for(int i=1;i<=n;i++)
int main() {
//表示要输入的行数
int row = 0;
int year, month, day, n;
scanf("%d\n", &row);
//表示有count行数据要处理
for (int i = 0; i <row; i++) {
scanf("%d%d%d%d\n", &year, &month, &day, &n);
for (int i = 1; i <= n; i++) {
NextDay(year, month,day);
}
printf("%04d-%02d-%02d\n", year, month, day);
}
}
要注意输出时写上换行符,这些OJ系统主要考察的就是这些细节。
结果:
知识点:
值传递和引用
1.我们每调用一个新的函数,就会调用一个新的栈帧
注意函数调用栈帧,调用时分配,返回时销毁。
2.使用值传递,参数传递是克隆出来的,即NextDay()中参数的变化不会改变调用它的main()中实参的值。
但我们现在的需求就是要让NextDay()中参数的改动对与之对应的main()中的实参有影响,故我们使用另一种参数传递的方式:引用。
3.引用,即起别名。使用引用方式传递的参数,被调函数NextDay()中对参数的操作实际上改变的是main()函数的栈帧里面的内容。
那怎么表示引用呢?
==》&出现在定义或形参当中,就表示引用。但如果出现在其他位置,表示取地址。
EOF
在C++中,EOF
(End of File)是一个常量,用来表示输入流的结束。它通常用于检测输入是否结束。scanf
会在无法读取更多有效数据时返回EOF
。
在上面程序中,while(scanf("%d%d%d\n",&year,&month,&day)!=EOF)
这行代码的作用是不断读取用户输入的年月日,直到输入结束为止。
for
循环的语法:
cpp复制编辑for (initialization; condition; increment) { // 循环体 }
-
初始化:
initialization
只会在第一次进入循环时执行一次,用来设置循环控制变量的初始值。 -
条件判断:
condition
在每次循环开始之前都会被执行一次,判断条件是否成立(即是否为真)。如果条件为假,循环就会结束。
-
递增:在每次循环体执行完毕后执行。