高斯日记:
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,
它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
#include<iostream>
using namespace std;
void DateAdd(int year,int month,int day,int plus){
int i;
int a[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; //12个月份的天数
for(i = 0; i < plus; i++){
if(month == 12&&day == 31){ //当12月31日时,年进一
year++;
month = 1;
day = 1;
continue; //加了一天后,跳出执行下一个循环
}
if((year%4 == 0 && year%100 != 0)||year%400 == 0){
a[1] = 29;
}
else a[1] = 28;
if(day == a[month-1]){ //月进一
month++;
day = 1;
continue; //加了一天后,跳出执行下一个循环
}
else day++; //日进一,这里加了一天后,直接执行下一个循环
}
cout<<year<<"-"<<month<<"-"<<day<<endl;
}
int main(){
DateAdd(1777,4,30,8113-1); //因为高斯标记的天数是当天,所以要减1
return 0;
}
另一个思路(但没有上一个代码通用性高):
#include <iostream>
using namespace std;
int a[20] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int leap(int y)
{
if(y%400 == 0 || (y%4==0 && y%100!=0))
return 1;
return 0;
}
int main()
{
int y,m,d;
const int Y = 1777,M = 4,D = 30;
int day=8113;
for(m = 5;m<=12;m++)
day-=a[m];
y = Y+1;
while(day>365)
{
if(leap(y))
day-=366;
else
day-=365;
y++;
}
if(leap(y))
a[2]++;
for(m = 1;m<=12;m++)
{
if(day<a[m])
break;
day-=a[m];
}
cout << y << "-" << m << "-" << day-1 << endl;
return 0;
}
星系炸弹:
在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。每个炸弹都可以设定多少天之后爆炸。
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。
有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。
#include<iostream>
using namespace std;
void DateAdd(int year,int month,int day,int plus){
int i;
int a[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
for(i = 0; i < plus; i++){
if(month == 12&&day == 31){
year++;
month = 1;
day = 1;
continue;
}
if((year%4 == 0 && year%100 != 0)||year%400 == 0){
a[1] = 29;
}
else a[1] = 28;
if(day == a[month-1]){
month++;
day = 1;
continue;
}
else day++;
}
cout<<year<<"-"<<month<<"-"<<day<<endl;
}
int main(){
int y,m,d,plus;
cout<<"请输入炸弹放置时间!"<<endl;
cout<<"年:";
cin>>y;
cout<<"月:";
cin>>m;
cout<<"日:";
cin>>d;
cout<<"请输入定时:";
cin>>plus;
DateAdd(y,m,d,plus);
return 0;
}
日期计算:
已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢400年闰的情况。
输入格式
输入只有一行
YYYY MM DD
输出格式
输出只有一行
W
数据规模和约定
1599 <= YYYY <= 2999
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
#include<iostream>
using namespace std;
void Week(int y,int m,int d){
int year = 2011, month = 11, day = 11, week = 5;
int a[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
while(!(year == y&&month == m&&day == d)){
if(month == 12&&day == 31){
year++;
month = 1;
day = 1;
week = (week+1)%7;
continue;
}
if((year%4 == 0 && year%100 != 0)||year%400 == 0){
a[1] = 29;
}
else a[1] = 28;
if(day == a[month-1]){
month++;
day = 1;
week = (week+1)%7;
continue;
}
else {
day++;
week = (week+1)%7;
}
}
if(week == 0)week = 7;
cout<<endl<<week<<endl;
}
int main(){
int y,m,d;
do{
cout<<"年:";
cin>>y;
cout<<"月:";
cin>>m;
cout<<"日:";
cin>>d;
}while((y < 1599 ||y > 2999)||(m < 1||m > 12)||(d < 1||d > 31));
Week(y,m,d);
return 0;
}
用基姆拉尔森计算公式:
/*分析
算法如下:
基姆拉尔森计算公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7 //C++计算公式
在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
如果使用基姆拉尔森计算公式:
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7
(需要使用switch...case语句判断星期几)
switch(week)
{
case 1: weekstr="星期一"; break;
case 2: weekstr="星期二"; break;
case 3: weekstr="星期三"; break;
case 4: weekstr="星期四"; break;
case 5: weekstr="星期五"; break;
case 6: weekstr="星期六"; break;
case 0: weekstr="星期日"; break;
}
改进:
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7+1
(计算出的结果直接是对应的星期几)
注意:
当month=1或2时,需要将其改为month+12并且year-1
*/
#include <stdio.h>
int main(void)
{
int year, month, day;
int x;
scanf("%d%d%d", &year, &month, &day);
if(month == 1 || month == 2)
{
month += 12;
year--;
}
x = (day + 2 * month + 3 * ( month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7 + 1;
printf("%d\n", x);
return 0;
}