ccf 201712-3 Crontab(100分)

 

 

提交后得100分的C++程序如下:

#include<bits/stdc++.h>
using namespace std;
const char *weeks_months[]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int leapyear(int year,int month) //处理闰年情况 
{
	if(month==2){
		return(((year%4==0)&&(year%100!=0))||(year%400==0))?1:0;
	}
	return 0;
}

vector<pair<int ,int> > v[5];
string cmd;//命令行
struct CMD{
	int id;
	long long time;
	string cmd;
	bool operator<(const CMD &a) const //排序 
	{
		return (time==a.time)? id>a.id: time>a.time;
	}
}; 
char buf[256];
int getval(char t[]) //根据月份,星期的英文得到数字 
{
	int i;
	t[0]=toupper(t[0]);//首字母大写
	for(i=1;t[i];i++) t[i]=tolower(t[i]);
	for(i=0;i<12+7;i++)
	{
		if(strcmp(t,weeks_months[i])==0) break;
	 } 
	if(i<12+7) return i<7? i:i-6;
	return -1;
}
void setsubval(char s[],vector<pair<int,int> >&v)//pair类型表示一个范围。任意的范围就用<-1,-1>表示 
{
	 int p1 = 0, p2 = 0;
    for(int i = 0; s[i]; i++)
        if(s[i] == '-') {
            s[i] = '\0';
            p2 = i + 1;
            break;
        }
 
    int val1, val2;
    if(p1 == p2) {
        if(isdigit(s[0]))
            val1 = atoi(s);
        else
            val1 = getval(s);
        v.push_back(make_pair(val1, val1));
    } else {
        if(isdigit(s[0]))
            val1 = atoi(s);
        else
            val1 = getval(s);
        if(isdigit(s[p2]))
            val2 = atoi(s + p2);
        else
            val2 = getval(s + p2);
        v.push_back(make_pair(val1, val2));
    }

}
void setval(char s[],vector<pair<int ,int> >&v){
	if(s[0]=='*') v.push_back(make_pair(-1,-1));
	else{
		char *p=strtok(s,",");
		while(p){
			setsubval(p,v);
			p=strtok(NULL,",");
		}
	}
}
int myatoi(char t[],int b,int e)
{
	int v=0;
	for(int i=b;i<=e;i++){
		v=v*10+t[i]-'0';
	}
	return v;
}
bool judge(int m,vector<pair<int,int> >& v){
	for(int i=0;i<(int)v.size();i++){
		if(v[i].first==-1||(v[i].first<=m&&m<=v[i].second))
		{
			return true;
		}
	}
	return false;
}
bool end_time_check(int y,int m,int d,int h,int mi, int ey, int em, int ed, int eh, int emi)
{
	if(y<ey) return true;
	if(m>em) return false;
	if(m<em) return true;
	if(d>ed) return false;
	if(d<ed) return true;
	if(h>eh) return false;
	if(h<eh) return true;
	if(mi>emi) return false;
	if(mi<emi) return true;
	return false;
}
int weekday(int year,int month,int day) //蔡勒公式 
{
    if(month == 1 || month == 2) {
        month += 12;
        year--;
    }
    int c = year / 100;
    int y = year % 100;
    int m = month;
    int d = day;
    int w = c / 4 - 2 * c + y + y / 4 + 26 * (m + 1) / 10 + d - 1;
    if(w < 0)
        return (w + (-w / 7 + 1) * 7) % 7;
    return w % 7;
}
int main(){
	int n;
	string s,t;
	priority_queue<CMD> q;
	cin>>n>>s>>t;
	strcpy(buf,s.c_str());
	int sy = myatoi(buf, 0, 3);
    int sm = myatoi(buf, 4, 5);
    int sd = myatoi(buf, 6, 7);
    int sh = myatoi(buf, 8, 9);
    int smi = myatoi(buf, 10, 11);
    strcpy(buf, t.c_str());
    int ey = myatoi(buf, 0, 3);
    int em = myatoi(buf, 4, 5);
    int ed = myatoi(buf, 6, 7);
    int eh = myatoi(buf, 8, 9);
    int emi = myatoi(buf, 10, 11);
    for(int i=0;i<n;i++){
    	string ss;//处理每行的分钟,小时,日,月份,星期
    	for(int j=0;j<5;j++){
    		v[j].clear();
    		cin>>ss;
    		strcpy(buf,ss.c_str());
    		setval(buf,v[j]);
		}
		cin>>cmd;
		int k=sm,l=sd,m=sh,n=smi;//月,日,小时,分钟循环 
		 for(int j = sy; j <= ey; j++, k=1)  // 年循环处理
            for(; k <= 12; k++, l = 1)
                if(judge(k, v[3]))
                    for(; l <= days[k] + leapyear(j, k); l++, m = 0)
                        if(judge(l, v[2]) && judge(weekday(j, k, l), v[4]))
                            for(; m < 24; m++, n = 0)
                                if(judge(m, v[1]))
                                    for(; n < 60; n++) {
                                        if(!end_time_check(j, k, l, m, n, ey, em, ed, eh, emi))
                                            break;
                                        if(judge(n, v[0])) {
                                            CMD tmp;
                                            tmp.id = i;
                                            tmp.time = (long long)j * 100000000 + (long long)k * 1000000 + (long long)l * 10000 + (long long)m * 100 + n;
                                            tmp.cmd = cmd;
                                            q.push(tmp);
                                        }
                                    }

	}
	while(!q.empty()){
		CMD tmp=q.top();
		q.pop();
		cout<<tmp.time<<" "<<tmp.cmd<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值