1. 程式人生 > >CCF計算機軟體能力認證試題練習:201712-3 Crontab

CCF計算機軟體能力認證試題練習:201712-3 Crontab

Crontab

來源:

標籤:

參考資料:

相似題目:

題目

這裡寫圖片描述

輸入

這裡寫圖片描述

輸出

這裡寫圖片描述

輸入樣例

3 201711170032 201711222352
0 7 * * 1,3-5 get_up
30 23 * * Sat,Sun go_to_bed
15 12,18 * * * have_dinner

輸出樣例

201711170700 get_up
201711171215 have_dinner
201711171815 have_dinner
201711181215 have_dinner
201711181815 have_dinner
201711182330 go_to_bed
201711191215 have_dinner
201711191815 have_dinner
201711192330 go_to_bed
201711200700 get_up
201711201215 have_dinner
201711201815 have_dinner
201711211215 have_dinner
201711211815 have_dinner
201711220700 get_up
201711221215 have_dinner
201711221815 have_dinner

樣例說明

這裡寫圖片描述

提示

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

解題思路

說幾個易錯點吧。1.需要判斷日期的合法性(某一天是否真實存在,需要結合某年某月的天數具體判斷,同時需要判斷這一天是星期幾)。2.排序操作:時間值小的先輸出;時間值相等的,按輸入順序輸出;時間值和名稱都相等的,應只輸出一個。3.包括開始時間,不包括結束時間。4.月份和星期幾可以字母表示,忽略大小寫。5.其它,請認真審題。

參考程式碼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<algorithm> #include<set> using namespace std; const char *month="janfebmaraprmayjunjulaugsepoctnovdec"; const char *weekday="sunmontuewedthufrisat"; int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; struct Command{ int no; //編號 long long time; //時間 char name[105]; //名稱 bool
operator < (const Command& rhs) const{ if(time==rhs.time) return no<rhs.no; return time<rhs.time; } bool operator == (const Command& rhs) const{ return strcmp(name,rhs.name)==0 && time==rhs.time; } }command[10005]; int tot;//對執行命令計數 int n; //輸入命令個數 long long startTime,finishTime; //開始時間和結束時間 char input[6][105]; //每條命令含有6個引數,type依次是【Minutes】【Hours】【day of month】【month】【day of week】【name】 set<int> timeRange[5];//時間值範圍集合,type依次是【Minutes】【Hours】【day of month】【month】【day of week】 set<int>::iterator M,H,dm,m;//對應上一行的前4個迭代器 void getTimeRange(int type, char *str);//對input[type]獲取時間值範圍 int addTimeRange(int type, int start, int finish);//對timeRange[type]增加時間值範圍 void addCommand();//對獲取到的時間值範圍新增命令 //工具類函式 int getValue(int &i, char *str);//從str[i]起得到一個時間值 long long getToday(int y,int m,int d);//計算今天的日期 int getDayofWeek(int y,int m,int d);//計算今天是星期幾 int main(){ scanf("%d%lld%lld",&n,&startTime,&finishTime); for(int i=0;i<n;i++){ for(int j=0;j<5;j++) timeRange[j].clear(); for(int j=0;j<6;j++){//讀入每條命令的6個引數,並對前5個引數處理 scanf("%s",input[j]); if(j!=5) getTimeRange(j,input[j]); } addCommand(); } sort(command,command+tot); tot=unique(command,command+tot)-command;//忽略重複的 for(int i=0;i<tot;i++) printf("%lld %s\n",command[i].time,command[i].name); return 0; } void getTimeRange(int type, char *str){ int start,finish; //處理星號表示的時間值範圍 if(str[0]=='*'){ if(type==0) start=0, finish=59; else if(type==1) start=0, finish=23; else if(type==2) start=1, finish=31; else if(type==3) start=1, finish=12; else if(type==4) start=0, finish=6; addTimeRange(type,start,finish); return; } //處理橫槓和逗號表示的時間值範圍 int i=0; int len=strlen(str); while(i<len){ start=getValue(i,str);//獲取一個值,如果後接'-',繼續獲取下一個值 if(str[i]=='-') finish=getValue(++i,str); else finish=start; addTimeRange(type,start,finish); } } void addCommand(){ long long today,time; int dayofWeek; int y1=startTime/1e8, y2=finishTime/1e8; int startDay=startTime/1e4; for(int y=y1;y<=y2;y++)//year for(m=timeRange[3].begin();m!=timeRange[3].end();m++)//month for(dm=timeRange[2].begin();dm!=timeRange[2].end();dm++){//day of month today=getToday(y,*m,*dm);//得到今天的日期 if(today>=startDay && timeRange[4].count(getDayofWeek(y,*m,*dm))){//今天是星期幾,是否在day of week中 for(H=timeRange[1].begin();H!=timeRange[1].end();H++)//Hours for(M=timeRange[0].begin();M!=timeRange[0].end();M++){//Minutes time=today*1e4+(*H)*1e2+(*M); if(time>=startTime && time<finishTime){ strcpy(command[tot].name,input[5]); command[tot].time=time; command[tot].no=tot; tot++; } else if(time>=finishTime) return; } } } } int getValue(int &i, char *str){ char value[105];int cnt=0; int len=strlen(str); while(i<len){ //如果是數值 if(isdigit(str[i])){ while(i<len && isdigit(str[i])){ value[cnt++]=str[i++]; } value[cnt]='\0'; return atoi(value); } //如果是字母 else if(isalpha(str[i])){ while(i<len && isalpha(str[i])){ value[cnt++]=tolower(str[i++]); } value[cnt]='\0'; char *p=strstr(month,value); if(p) return (p-month)/3+1; else if(p=strstr(weekday,value)) return (p-weekday)/3; } else i++; } return -1; } int addTimeRange(int type,int start,int finish){ for(int i=start;i<=finish;i++){ timeRange[type].insert(i); } } long long getToday(int y,int m,int d){ if(y%4==0 && y%100!=0 || y%400==0) days[1]=29; else days[1]=28; if(d>days[m-1]) return -1; return y*1e4+m*1e2+d; } int getDayofWeek(int y,int m,int d){ if(m==1||m==2){ m+=12; y--; } return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7; }