一、目标
实现下面4道练习题增强C++代码能力。
1.求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)
2.计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com)
3.日期差值_牛客题霸_牛客网 (nowcoder.com)
4.打印日期_牛客题霸_牛客网 (nowcoder.com)
二、对目标的实现
1.求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)
思路讲解:
对于这道题来说,通过描述可知,求前n项和这一操作如果没有限制的话想必大家都会,但这题的复杂点就在于后一句:要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。这句话说白了就是限制了你使用循环和递归等操作,那么我们该怎么解决这个问题呢。
那么我们现在就可以借助在C++类和对象中介绍的静态成员函数和静态成员变量来解决这一问题。对于具体介绍静态成员函数和静态成员变量在这里 C++_类和对象(下篇)-CSDN博客
首先,我们需要在类中定义两个静态成员变量,这里利用的是静态成员变量的生命周期,是在整个函数程序结束后才释放销毁。
然后我们这里通过的是变长数组的原理来实现的,我们需要在类中定义一个构造函数,然后两个静态成员变量中,一个是用于统计求加和的,一个是用来统计++的,所以这这里我们需要对用于加和的那个静态成员变量初始化为0,用于统计++的那个成静态成员变量初始化为1。
class SUM
{
public:
SUM()
{
_ret+=_i;
++_i;
}
static int Get_ret()
{
return _ret;
}
private:
static int _i;
static int _ret;
};
int SUM::_i=1;
int SUM::_ret=0;
最后,我们通过类初始化一个长度为n的数组,来调用n次构造函数,这样也就相当于实现了循环,也就在满足了题意的情况下解决了这一问题,接着,我们就通过,类中的静态成员函数,来返回这个值。这样我们就解决这一问题啦!
代码实现:
class SUM
{
public:
SUM()
{
_ret+=_i;
++_i;
}
static int Get_ret()
{
return _ret;
}
private:
static int _i;
static int _ret;
};
int SUM::_i=1;
int SUM::_ret=0;
class Solution {
public:
int Sum_Solution(int n) {
SUM a[n];
return SUM::Get_ret();
}
};
2.计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com)
思路讲解:
这题的思路就是先定义一个获取该月份下的天数的函数,然后我这里的思路就是从一月份开始一直加到你所输入的那个月份,然后将输入月份前面月份的天数和输入的天数求和,这样求出来的天数,就是x年x月x日在x年中的第几天。
代码实现:
#include <iostream>
using namespace std;
//因为平年闰年的2月天数不一样所以我们需定义一个获取月份的函数来解决这一问题
int GetMonth_day(int year, int month) //获取该月份的天数
{
static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
{
return 29;
}
else
{
return daysArr[month];
}
}
int main()
{
int year,month,day;
cin>>year>>month>>day;
int _month=1;
while(_month!=month)
{
day+=GetMonth_day(year,_month);
++_month;
}
cout<<day<<endl;
return 0;
}
3.日期差值_牛客题霸_牛客网 (nowcoder.com)
思路讲解:
这道题有上一道题铺垫,所以说我们可以利用上道题的知识直接求出x年x月x日的天数。然后在比较年份之间的大小,接着就直接求年份之间天数的差值,然后求上面所求x年x月x日的天数之间天数的差值,最后求和即可。
代码实现:
#include <iostream>
using namespace std;
int GetMonth_day(int year, int month)
{
static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
{
return 29;
}
else
{
return daysArr[month];
}
}
int main()
{
//求出第一次输入的年的天数
int year1,month1,day1;
scanf("%04d%02d%02d",&year1,&month1,&day1);
int _month=1;
while(_month!=month1)
{
day1+=GetMonth_day(year1,_month);
++_month;
}
//求出第二次输入的年的天数
int year2,month2,day2;
scanf("%04d%02d%02d",&year2,&month2,&day2);
_month=1;
while(_month!=month2)
{
day2+=GetMonth_day(year2,_month);
++_month;
}
int day=0;
if(year1>year2)
{
day=day1-day2; //求两次输入的数据月日之间天数的差值
while(year1!=year2)
{
if ((year2 % 4 == 0 && year2 % 100 != 0) || (year2 % 400 == 0))
{
day+=366;
}
else
{
day+=365;
}
++year2;
}
}
else
{
day=day2-day1; //求两次输入的数据月日之间天数的差值
while(year1!=year2)
{
if ((year1 % 4 == 0 && year1 % 100 != 0) || (year1 % 400 == 0))
{
day+=366;
}
else
{
day+=365;
}
++year1;
}
}
//有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
//所以我们所得到的结果应为day+1.
cout<<(day+1)<<endl;
return 0;
}
4.打印日期_牛客题霸_牛客网 (nowcoder.com)
思路讲解:
对于这道题,我们敲过了日期类,所以说对于这道题,我们可以先定一个日期类。
然后内容包括日期类的构造函数和求当前月份下的天数的函数,以及求+=运算符重载,和打印函数即可。
代码实现:
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year,int month=1,int day=1)
:_year(year)
,_month(month)
,_day(day)
{}
int GetMonth_day(int year,int month);
Date& operator+=(int day);
void Print()const
{
printf("%04d-%02d-%02d",_year,_month,_day);
}
private:
int _year;
int _month;
int _day;
};
int Date::GetMonth_day(int year, int month)
{
static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
{
return 29;
}
else
{
return daysArr[month];
}
}
Date& Date::operator+=(int day)
{
_day+=day-1;
while(_day>GetMonth_day(_year, _month))
{
_day-=GetMonth_day(_year, _month);
++_month;
if(_month==13)
{
_month=1;
++_year;
}
}
return *this;
}
int main()
{
int year,day;
cin >> year >> day;
Date s1(year);
s1+=day;
s1.Print();
return 0;
}
三、结语
上述内容,即是我个人对通过C++解决这些习题个人见解。若有大佬发现哪里有问题可以私信或评论指教一下。非常感谢各位uu们的点赞,关注,收藏,还望各位多多关照,让我们一起进步吧!