CSP-2017-12-3-Crontab

Crontab题目的详细信息(传送门)

我太难了,这个题,在一下午的时间之后只有95分,还有一个测试点错误,实在找不到了。

做题的时候千万注意细节:

第一、那个时间点时左闭右开,这个有30分的测试点
第二、每个月的天数也要注意,后来没有注意这个判断
第三、注意补0操作
第四、注意大小写(月份和星期的)

从5分到95分的我其实已经快疯了,ε=(´ο`*)))

输入:

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

下面是95分代码,大佬路过的话可以帮我看一下么♪(・ω・)ノ

#include <bits/stdc++.h>

using namespace std;

int monthDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

//判断是否是闰年
bool isLunarYear(int year){
    return (year%4 == 0 && year%100 ) || (year%400 == 0);
}

//字符串转换为数字
int string_to_num(string str){
	int num;stringstream ss;
    ss << str;ss >> num;
	return num;
}

//数字转换为字符串
string num_to_string(int num){
	string str;stringstream ss;
    ss << num;ss >> str;
	return str;
}
//将所有字母转化为小写
void string_to_lower(string &str){
	transform(str.begin(), str.end(), str.begin(), ::tolower);
}

//将月份或星期转换为数字方便计算
void mw_to_num(string &str) {
	string_to_lower(str);int num=-1;
 	string month[12] = { "jan","feb","mar","apr","may","jun","jul",
						"aug","sep","oct","nov","dec" };//12个月
	string week[7] = { "sun","mon","tue","wed","thu","fri","sat" };//一个星期
	for (int i = 0; i < str.length(); i++) {
		if (str[i] >= 'a' && str[i] <= 'z') {
			string mon_or_week = str.substr(i, 3);
			for (int j = 0; j < 12; j++)
				if (mon_or_week == month[j])
					num = j + 1;
			for (int j = 0; j < 7; j++)
				if (mon_or_week == week[j])
					num = j;
            if(num != -1){
            	string s = num_to_string(num);
				str.replace(i, 3, s);
			}
			num = -1;
		}
	}
}

//判断某年某月某日是星期几
int getDayOfWeek(int year, int month, int day){
    int nowDay = 0;
    for (int i = 1970; i <= year - 1; i++){
        if (isLunarYear(i)){
        	nowDay += 366;
		}
        else{
        	nowDay += 365;
		}
    }
    for (int i = 0; i < month-1; i++){
        if (isLunarYear(year) && i == 1){
        	nowDay += 29;
		}
        else{
        	nowDay += monthDay[i];
		}
    }
    nowDay += day;
    nowDay = nowDay % 7;//按理说此时应该就可以,但是题目中说1970.1.1是星期四,所以是应该再计算一次
    nowDay = (nowDay + 3) % 7;
    return nowDay;
}

//处理'*'字符
void deal1(string &str,string name){
	if(str == "*"){
		if(name == "minute"){
			str = "0-59";
		}else if(name == "hour"){
			str = "0-23";
		}else if(name == "day"){
			str = "1-31";
		}else if(name == "month"){
			str = "1-12";
		}else if(name == "week"){
			str = "0-6";
		}
	}
}

//处理'-'字符
void deal2(string &str){

	int pos = str.find("-");
	while(pos != string::npos){
		int i = pos+1;
		while(str[i]>='0' && str[i]<= '9'){
			i++;
			if(str[i] == ','){
				i--;
				break;
			}
		}
		string ss = str.substr(pos+1,i-pos);
		int maxx = string_to_num(ss);

		i = pos-1;
		while(str[i]>='0' && str[i]<= '9'){
			i--;
			if(i<0){
				i = 0;
				break;
			}
			if(str[i] == ','){
				i++;
				break;
			}
		}
		ss = str.substr(i,pos-i);
		int minn = string_to_num(ss);

		pos = str.find("-");
		str.erase(pos,1);
		i = 0;
		for(int j = minn+1; j < maxx;j++){
			string s = ","+num_to_string(j);
			str.insert(pos+i,s);
			i += s.size();
		}
		str.insert(pos+i,",");
		pos = str.find("-");
	}
}

//处理','并将所有符合的存到vec中
void deal3(string str,vector<string> & vec){
	string s;
	str += ",";
	for(int i = 0; i < str.size(); i++){
		if(str[i] == ','){
			vec.push_back(s);
			s = "";
		}else{
			s += str[i];
		}
	}
}

//判断某天是星期几是否存在,用vector是否存在某元素是否存在
bool judge(string str,vector<string> vec){
	vector<string>::iterator iter = find(vec.begin(), vec.end(), str);
	if(iter != vec.end()){
		return true;
	}
	return false;
}

//排序问题
struct node{//为了解决时间一样时按顺序来所以把key设成一个结构体
	string key;
	int i;
	bool operator < (const node &n) const{
		return key < n.key;
	}
};
typedef pair<node, vector<string> > PAIR;
bool cmp(const PAIR& x, const PAIR& y){
	if(x.first.key == y.first.key){//当在一个时间点时,按顺序来
		x.first.i < y.first.i;
	}
	return x.first.key < y.first.key;//否则的话从小到大来一遍
}


int main(){
	string str,s,t;int n;
	cin >> n >> s >> t;cin.get();

	string year1=s.substr(0,4);
    string year2=t.substr(0,4);

    map<node,vector<string> > mResult;
	for(int i = 0; i < n; i++){
		int y1=string_to_num(year1);int y2=string_to_num(year2);
		string minute,hour,day,month,week,command;
		vector<string> vMM,vHH,vdd,vmm,vww;

		getline(cin,str);
		istringstream line(str);
		line >> minute >> hour >> day >> month >> week >> command;
		deal1(minute,"minute");deal1(hour,"hour");deal1(day,"day");deal1(month,"month");deal1(week,"week");
		mw_to_num(month);mw_to_num(week);
		deal2(minute);deal2(hour);deal2(day);deal2(month);deal2(week);
		deal3(minute,vMM);deal3(hour,vHH);deal3(day,vdd);deal3(month,vmm);deal3(week,vww);
		node nod;nod.i = i;
		while(y1 <= y2){
			if(isLunarYear(y1)){
				monthDay[1] = 29;
			}else{
				monthDay[1] = 28;
			}
			for(int i = 0; i < vmm.size(); i++){
				string mon = vmm[i];//几月份
				for(int j = 0; j < vdd.size(); j++){
					string dd = vdd[j];//几号
					string ww = num_to_string(getDayOfWeek(y1,string_to_num(mon),string_to_num(dd)));//星期几
					if(judge(ww,vww) && string_to_num(dd) <= monthDay[string_to_num(mon)-1]){//这个必须判断,不然只有30分,天必须小于当月天数
                        for(int k = 0; k < vHH.size(); k++){
                        	for(int m = 0; m < vMM.size(); m++){
                        		if(mon.size()==1)mon = "0"+mon;//一堆补0操作
                        		if(dd.size()==1)dd = "0"+dd;
                        		if(vHH[k].size()==1)vHH[k]="0"+vHH[k];
                        		if(vMM[m].size()==1)vMM[m]="0"+vMM[m];
                        		string alltime = num_to_string(y1)+mon+dd+vHH[k]+vMM[m];
                        		if(alltime>=s && alltime<t){//左闭右开,啊啊啊啊啊啊啊啊啊啊啊啊,此处一直有70分,卡住
									nod.key = alltime;
									mResult[nod].push_back(command);
								}
							}
						}
					}
				}
			}
			y1++;
		}
	}

	vector<PAIR> vec(mResult.begin(),mResult.end());
	sort(vec.begin(), vec.end(), cmp);
	for (int i = 0; i < vec.size(); i++) {
		for(int j = 0; j < vec[i].second.size(); j++){
			cout << vec[i].first.key <<" "<<vec[i].second[j] << endl;
		}
  	}
	return 0;
}

这里是题目O(∩_∩)O,欢迎大家留言,有空的话可以点个赞哦(#^ . ^#)

          试题编号:
201712-3
试题名称: Crontab
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
发布了42 篇原创文章 · 获赞 40 · 访问量 973

猜你喜欢

转载自blog.csdn.net/weixin_44635198/article/details/104502242
今日推荐