【C++】类与对象OJ题目求1+2+3+…+n,计算一年的第几天,日期差值,打印日期,日期累加

发布于:2025-05-18 ⋅ 阅读:(23) ⋅ 点赞:(0)


在这里插入图片描述

题目一 :求1+2+3+…+n

题目描述:
 求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例:
 输入:5
 返回值:15

分析:
 若是只看题目不管要求,这是一道非常简单的题目,我们有好几种方式可以得出最终结果,但加上题目限制条件,可能大多数博友都懵了。
我们来捋一捋:
 1、不能使用乘除法,等差数列求和公式不能用了。
 2、不能使用for、while,循环求解不能用了。
 3、不能使用switch、case和A?B:C,递归求解也不能用了。
思路:
这道题不能用常规的方法进行解析,常规的方法已经被限制了。这里我们可以用构造函数的特性,我们知道在C++在创建一次新对象时,就会调用一次默认构造函数,我们可以用构造开辟数组的方法,调用n次默认构造函数,达到等差数列求和的效果

class Add
{
public:
	Add()
	{
		_num++;
		_ret += _num;
	}
	static int _ret;
	static int _num;

};
int Add::_ret = 0;
int Add::_num = 0;
class solution
{
public:
	int Sum_Solution(int n)
	{
		Add::_num = 0;
		Add::_ret = 0;
		Add* p = new Add[n];//调用n次默认构造函数,达到等差数列求和的效果

		return Add::_ret;
	}
};

题目二:计算一年的第几天

题目描述:
 根据输入的日期计算是这一年的第几天。

示例:
 输入:2021 7 18
 输出:199

思路:
题目的意思是给定义一个日期,计算这一天是今年的多少天,假设每个月都有31天,我们只需要计算n-1个月+day就好了。所以思路转换一下,我们将每个月的天数写出来,结果也就是n-1月的天数+day。

#include <iostream>
using namespace std;
int main()
{
	int year, month, day;
	cin >> year >> month >> day; //输入日期

	int daysArray[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; //daysArray[i]表示1月-i月的总天数(默认2月为28天)
	int totalDay = daysArray[month - 1] + day; //总天数
	if ((month > 2) && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) //如果所给日期为3月及以上,并且该年为闰年
	{
		totalDay += 1; //总天数+1(2月29日)
	}

	cout << totalDay << endl; //输出总天数,即该日期为该年的第几天
	return 0;
}

题目三:日期差值

题目描述:
 有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定它们之间的天数为两天。

示例:
 输入:19700101
    20210718
 输出:18827

思路:
根据所给的两个日期,分别得到两个日期的年、月、日,然后先计算出这两个日期年相差的天数,得到的值减去第一个日期当年的天数,再加上第二个日期当年的天数即可,但是题目规定:如果两个日期是连续的,那么题目之间的天数为两天。这意味着我们需要计算的日期差值为闭区间 [date1, date2],所以输出结果时需要再加上1。

#include <iostream>
using namespace std;
//判断是否为闰年
bool IsLeapYear(int year)
{
	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
int main()
{
	int date1, date2; //存储两个日期
	int year1, year2, month1, month2, day1, day2; //存储两个日期的年、月、日
	int ret = 0; //存储两个日期的差值
	int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //dayArray[i]代表i月的天数(平年)
	while (cin >> date1 >> date2) //多组测试数据
	{
		//确保第一个日期比第二个日期小
		if (date1 > date2)
		{
			int tmp = date1;
			date1 = date2;
			date2 = tmp;
		}
		//根据两个日期得到其年、月、日
		year1 = date1 / 10000, year2 = date2 / 10000;
		day1 = date1 % 100, day2 = date2 % 100;
		month1 = date1 % 10000 / 100, month2 = date2 % 10000 / 100;
		//计算年相差的天数
		for (int year = year1; year < year2; year++)
		{
			if (IsLeapYear(year))
				ret += 366;
			else
				ret += 365;
		}
		auto getCurYearDays = [&dayArray](int year, int month, int day)->int{
			int total = 0;
			for (int i = 1; i < month; i++) {
				total += dayArray[i];
				if (i == 2 && IsLeapYear(year))
					total++;
			}
			return total + day;
		};
		//减去date1当年的天数
		int days1 = getCurYearDays(year1, month1, day1);
		ret -= days1;
		//加上date2当年的天数
		int days2 = getCurYearDays(year2, month2, day2);
		ret += days2;
		ret++; //结果为闭区间[date1, date2],所以需要再加1
		cout << ret << endl;
	}
	return 0;
}


题目四:打印日期

题目描述:
 给出年份m和一年中的第n天,计算出第n天是几月几号。

示例:
 输入:2021 100
 输出:2021-04-10
思路:
从一月份开始,总天数减去每月的天数作为新的天数,若新的天数仍然大于当月的月份天数,那么则继续判断。

	#include <iostream>
using namespace std;
int main()
{
	int year, day;
	int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //dayArray[i]代表i月的天数(平年)
	while (cin >> year >> day) //多组测试数据
	{
		int month = 1; //month从1月开始
		if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //判断该年是否为闰年
			dayArray[2] += 1; //闰年2月为29天
		//使日期合法
		while (day > dayArray[month])
		{
			day -= dayArray[month];
			month++;
		}
		printf("%d-%02d-%02d\n", year, month, day); //按格式输出
	}
	return 0;
}

题目五:日期累加

题目描述:
 设计一共程序能计算一个日期加上若干天后是什么日期。

输入描述:
 输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。

输出描述:
 输出m行每行按yyyy-mm-dd的格式输出。

示例:
 输入:2
    2021 7 18 100
    2021 1 1 100
 输出:2021-10-26
    2021-04-11
先将需要累加的天数加到“日”上,然后通过不断的迭代使得日期合法,迭代过程如下:判断“日”是否大于该年该月的总天数,若大于,则将“日”减去该月的总天数后作为新的“日”,然后将月份加一,继续进行判断;若小于,则结束判断,输出日期即可。需要注意:每次月份加一后需要判断“年”是否需要进位,若需要进位还需判断进位后的年是否为闰年。

#include <iostream>
using namespace std;
//判断是否为闰年
bool IsLeapYear(int year)
{
	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
int main()
{
	int m, year, month, day, n;
	int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //dayArray[i]代表i月的天数(平年)
	cin >> m; //读取样例个数
	for (int i = 0; i < m; i++)
	{
		cin >> year >> month >> day >> n; //读取年、月、日和需要累加的天数
		if (IsLeapYear(year))
			dayArray[2] = 29; //闰年2月设置为29天
		day += n; //先将需要累加的天数加到“日”上
		//使日期合法
		while (day > dayArray[month])
		{
			day -= dayArray[month];
			month++;
			if (month == 13) //“年”需要进位
			{
				year++;
				month = 1;
				//判断新的一年是否为闰年
				if (IsLeapYear(year))
					dayArray[2] = 29; //闰年2月设置为29天
				else
					dayArray[2] = 28; //平年2月设置为28天
			}
		}
		printf("%d-%02d-%02d\n", year, month, day); //按格式输出
	}
	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到