目录
时间(日期)在OI中的应用
时间在很多领域都有所应用,其中不乏OI(信息竞赛),下面给大家举一些列子以及相应代码,让你更充分地了解时间。
平闰年
公历年份是4的倍数且不是100的倍数,或公历年份是400的倍数位闰年(四年一闰,百年不闰,四百年再闰),闰年二月有29天。
P5711 闰年判断
输入一个年份,判断这一年是否是闰年,如果是输出 1 1 1,否则输出 0 0 0。
直接按照前面说说规律判断即可。
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int y;
bool p1,p2,p3;
cin>>y;
p1=y%4==0;
p2=y%100==0;
p3=y%400==0;
cout<<(p3||p1&&!p2);
return 0;
}
P5737 闰年展示
输入 x , y x,y x,y,输出 [ x , y ] [x,y] [x,y] 区间中闰年个数,并在下一行输出所有闰年年份数字,使用空格隔开。
依次遍历 x x x 到 y y y,每次判断是否为闰年即可。
#include<bits/stdc++.h>
using namespace std;
int x,y,ans[1000],num;
int main(){
cin>>x>>y;
for(int i=x;i<=y;i++){
if(!(i%400)||!(i%4)&&i%100){
ans[num++]=i;
}
}
cout<<num<<endl;
for(int i=0;i<num;i++){
cout<<ans[i]<<" ";
}
return 0;
}
P5716 月份天数
输入年份和月份,输出这一年的这一月有多少天。需要考虑闰年。
一,三,五,七,八,十,十二月为大月,31天。
四,六,九,十一为小月,30天。
二月平年28天,闰年29天。
直接判断平闰年,输出对应月份天数即可
#include<iostream>
using namespace std;
int main(){
int y,m;
cin>>y>>m;
switch(m){
case 1: case3: case 5: case 7: case 8: case 10: case 12:
cout<<31<<endl;break;
case 4: case 6: case 9: case 11:
cout<<30<<endl;break;
case 2: if((y%400==0)||(y%4==0)&&!(y%100==0)){
cout<<29<<endl;
}else cout<<28<<endl;
break;
default: break;
}
return 0;
}
日期推算
P5690 [CSP-S2019 江西] 日期
给定一个日期,问至少要改动几个数字才能使这个日期存在
#include<bits/stdc++.h>
using namespace std;
int m,d;
int main(){
scanf("%d-%d",&m,&d);
if(d>0&&d<=28){//所有月份都满足
if(m>0&&m<=12){
cout<<"0";
}else {
cout<<"1";//只改变月份的十位
}
}else if(d==29||d==30){//大小月皆满足
if(m==0||m==2||m>12){//改十位
cout<<"1";
}else{
cout<<"0";
}
}else if(d==31){
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12){//大月满足
cout<<"0";
}else if(m==2||m==4||m==6||m==9||m%10==1){//改变个位(最后一种改十位)
cout<<"1";
}else if(m%10==4||m%10==6||m%10==9){//改十位和个位
cout<<"2";
}else{//只改十位
cout<<"1";
}
}else if(m==0||m>12){ //日期月份都改十位
cout<<"2";
}else{//日期改十位
cout<<"1";
}
return 0;
}
P2010 [NOIP2016 普及组] 回文日期
给定起始日期和终止日期,问期间有多少回文日期(不满8位数要补零)
#include<bits/stdc++.h>
using namespace std;
int l,r,ans;
int main(){
cin>>l>>r;
int a=l/10000;
int b=r/10000;//分离出年份
for(int i=a;i<=b;i++){
int mon=i/10%10+i%10*10;
int day=i/1000+i%1000/100*10;//分离出月份日期
if(mon<=0||mon>12||day<=0||day>31||i*10000+mon*100+day<l||i*10000+mon*100+day>r) continue; //不是真实日期或不满足要求
if(mon==2){
if(day>29) continue;//不是真实日期
if(day==29){
if(!((i%4==0&&i%100!=0)||i%400==0)){//不是闰年但有29天
continue;
}
}
}
if((mon==4||mon==6||mon==9||mon==11)&&day==31) continue;//不是大月但又31天
ans++;
}
cout<<ans;
return 0;
}
AT_utpc2012_01 2012年12月02日
若月份和天数组成的四位数重新排列后可以变成年份,则该日期为好日子,给定一个日期,问其是否为好日子
#include<bits/stdc++.h>
using namespace std;
string s;
int y,m,d;
int vis1[12],vis2[12];
int main(){
cin>>s;
y=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0');//分离年份
m=(s[5]-'0')*10+(s[6]-'0');//分离月份
d=(s[8]-'0')*10+(s[9]-'0');//分离天数
vis1[y%10]++,vis1[y%100/10]++,vis1[y%1000/100]++,vis1[y/1000]++;
vis2[m/10]++,vis2[m%10]++,vis2[d/10]++,vis2[d%10]++;
for(int i=0;i<=9;i++){
if(vis1[i]!=vis2[i]){//若某一数字在年份和月日组成的数中数量不等,则不是好日子
cout<<"no"<<endl;
return 0;
}
}
cout<<"yes"<<endl;
return 0;
}
ARC015B 真冬日?真夏日?
直接判断即可
#include<bits/stdc++.h>
using namespace std;
int n;
int a[10];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
float x,y;
cin>>x>>y;
if(x>=35.0) a[1]++;
else if(x>=30.0) a[2]++;
else if(x>=25.0) a[3]++;
if(y>=25.0) a[4]++;
if(x>=0.0&&y<0.0) a[5]++;
if(x<0.0) a[6]++;
}
cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<" "<<a[5]<<" "<<a[6]<<endl;
return 0;
}
扩展
时间差(时区)
P8831 [传智杯 #3 练习赛] 儒略历
#include<bits/stdc++.h>
using namespace std;
string s;
int y,m,d,ans;
int mm[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int getm(string x){//得到月份
if(x[0]=='J'){
if(x[1]=='A') return 1;
if(x[2]=='N') return 6;
return 7;
}
if(x[0]=='F') return 2;
if(x[0]=='M'){
if(x[2]=='R') return 3;
return 5;
}
if(x[0]=='A'){
if(x[1]=='P') return 4;
return 8;
}
if(x[0]=='S') return 9;
if(x[0]=='O') return 10;
if(x[0]=='N') return 11;
return 12;
}
int gety(string x){//得到年份
int y=0;
for(int i=0;i<x.size();i++){
y=y*10+x[i]-'0';
}
return y;
}
int main(){
cin>>s;
if(s[1]>='A'&&s[1]<='Z'){
d=s[0]-'0';
m=getm(s.substr(1,3));
y=gety(s.substr(4));
}else{
d=(s[0]-'0')*10+s[1]-'0';
m=getm(s.substr(2,3));
y=gety(s.substr(5));
}
//除今年外全满的年
for(int i=1;i<y;i++){
if(i<1582){//儒略历
if(i%4==0) ans+=366;
else ans+=365;
}else{//格里高利历
if(i%400==0||(i%4==0&&i%100!=0)) ans+=366;
else ans+=365;
}
//闰年判别不同
}//除了今月外全满的月
for(int i=1;i<m;i++){
ans+=mm[i];
}
if((y%400==0||(y%4==0&&y%100!=0))&&m>2) ans++;//闰年二月
ans+=d;//加上日期
if(y>1582) ans-=10;//格里高利历
if(y==1582&&m>=10&&d>=15) ans-=10;//格里高利历
cout<<ans-1<<endl;//减去公元元年一月一日(起始日)
return 0;
}
扩展
UVA10371 Time Zones
#include<bits/stdc++.h>
using namespace std;
int n;
float a[10];
float get(string s){
if(s=="UTC"||s=="GMT"||s=="WET") return 0;
else if(s=="BST"||s=="IST"||s=="WEST"||s=="CET") return 1;
else if(s=="CEST"||s=="EET") return 2;
else if(s=="EEST"||s=="MSK") return 3;
else if(s=="MSD") return 4;
else if(s=="AWST") return 8;
else if(s=="ACST") return 9.5;
else if(s=="AEST") return 10;
else if(s=="ACDT") return 10.5;
else if(s=="AEDT") return 11;
else if(s=="NDT") return -2.5;
else if(s=="ADT") return -3;
else if(s=="NST") return -3.5;
else if(s=="EDT"||s=="AST") return -4;
else if(s=="EST"||s=="CDT") return -5;
else if(s=="CST"||s=="MDT") return -6;
else if(s=="MST"||s=="PDT") return -7;
else if(s=="PST"||s=="AKDT") return -8;
else if(s=="AKST") return -9;
else return -10;
}
void print(int x,int y){
if(x==0) x=12;
cout<<x<<":";
if(y<10) cout<<0;
cout<<y<<" ";
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
string a,b,c,d;
cin>>a;
if(a[0]=='n'||a[0]=='m') cin>>c>>d;
else cin>>b>>c>>d;
int x=0,y;
float dx=get(c),dy=get(d);//在前面加上两天(2880分钟)以防往前推算时变为负数
if(a=="noon") x=3600;
else if(a=="midnight") x=2880;
else {
if(b=="a.m."){
x+=2880;
}else {
x+=3600;
}
if(a.size()==4) x+=(a[0]-'0')*60+(a[2]-'0')*10+a[3]-'0';
else x+=(((a[0]-'0')*10+(a[1]-'0'))%12)*60+(a[3]-'0')*10+a[4]-'0';
}
// cout<<x<<endl;
if(dx==dy){
if(a[0]=='n'||a[0]=='m') cout<<a<<endl;
else cout<<a<<" "<<b<<endl;
continue;
}
float cha=abs(dx-dy);//时区相差小时数
if(dx>dy){
y=x-cha*60;
}else y=x+cha*60;
// cout<<y<<endl<<cha<<endl;
y=y%1440;
if(y==720){
cout<<"noon"<<endl;
continue;
}
if(y==0){
cout<<"midnight"<<endl;
continue;
}
int h=(y/60-1)%12+1,m=y%60;
print(h,m);
if(y>720) b="p.m.";//判断上下午
else b="a.m.";
cout<<b<<endl;
}
return 0;
}
UVA700 Date Bugs
#include<bits/stdc++.h>
using namespace std;
int n,cnt;
struct year{
int now,st,ed;
}a[30];
bool cmp(year x,year y){
return (x.ed-x.st)>(y.ed-y.st);
}
int main(){
cin>>n;
while(n){
cnt++;
for(int i=1;i<=n;i++){
cin>>a[i].now>>a[i].st>>a[i].ed;
}
sort(a+1,a+1+n,cmp); //转化为等差数列的公差,公差越大枚举次数越少
int ny=a[1].now,ans=-10;
while(ny<10000){
bool f=0;
for(int i=2;i<=n;i++){
if(ny<a[i].now){
f=1;
break;
}
if((ny-a[i].now)%(a[i].ed-a[i].st)!=0){//看是否与其他表示方式冲突(无法获得该日期)
f=1;
break;
}
}
if(!f){
ans=ny;
break;
}
ny+=a[1].ed-a[1].st;
}
if(ans!=-10){
printf("Case #%d:\nThe actual year is %d.\n\n",cnt,ans);
}else{
printf("Case #%d:\nUnknown bugs detected.\n\n",cnt);
}
//记得换行
cin>>n;
}
return 0;
}
扩展
B2074 计算星期几 链接
AT_code_festival_qualA_c 2月29日 链接
P8651 [蓝桥杯 2017 省 B] 日期问题 链接
P8748 [蓝桥杯 2021 省 B] 时间显示 链接
AT_arc023_1 [ARC023A] 経過日数 链接
P8547 小挖的时间 链接
P8665 [蓝桥杯 2018 省 A] 航班时间 链接
UVA518 Time 链接
P7267 [BalticOI 2000] Time Zones 链接
一些关于时间的网站
timeanddate.com
timeanddate.com
timeanddate.com的主页,可见其覆盖面之广。
世界时区图,非常详细。
Codeforces.com 的应用(红框内)。
AtCoder.jp 的应用(红框内)。
Uoj.ac 也有其应用。
time.is
Time.is 的主页,简约风。
纽约地区的详细内容。
包括该城市所在的国家的一些知名城市,时区,时间差,日出,日落,昼长,太阳时,地图上的位置(海拔,人口,经纬度),年均气温(少数城市有数据)。
结语
时间可以说是最公平的东西之一了。
每个人的时间同时在流逝,不因谁的职业,社会地位,年龄,性别而改变,所以只有掌握分配时间的方法,才能让每一天有尽可能多的进步,从而有更多机遇和选择的权利。
电影《超体》中有一个片段:一辆小车在环形公路上行驶,当无限加速其运动时,它最终却会消失,而时间则是唯一证明它存在过的东西。
愿时间能记录下我们每个人的奋斗与欢喜,证明我们曾经热爱过……