CCF 201712-3 Crontab JAVA版本 仅得80分

博客内容介绍了如何使用JAVA代码实现Cron任务解析,针对CCF CSP的问题,博主选择了通过不断迭代当前时间并检查是否匹配Cron表达式的方式来解决,而非一次性计算所有可能的时间点。这种方法虽然逻辑简单,但因为时间复杂度较高,在比赛中获得了80分。文章提到了泰勒公式用于计算星期,并分享了代码思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先上题
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
样例输入

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


本人是用JAVA代码写的:
有两种思路:
第一种思路是根据配置文件计算出所有时间内的命令,并排序,然后输出。
第二种思路是根据开始时间计算,然后计算每一分钟,并进行对配置文件进行比较,合适的就输出,这个不用排序,知道达到结束时间,相对于第一种来说逻辑简单,但是时间复杂度高,因此才得了80分。

我采用的是第二种,这里简要说一下下面代码的思路:
1.用配置文件进行和当前时间比较
2.当前时间加1
3.当前时间是否结束
其中会用到计算星期:我这里用的是泰勒公式来计算星期:w=(y+[y/4]+[c/4]-2c+26(m+1)/10+d-1)mod 7
w:星期(0为星期天 1-6为星期一-六)
m:月份(3-14 1、2月份看为上一年的13、14月,所以此时就需要年份-1)
y:世纪-1
c:年的后两位

代码:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*
 * 运行超时  201712-3 最高85分 
 * 
 */
public class Main{
	static public String[] string;
	static public String[] a;
	static public String tmp;
	static public int c;
	static public int y;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		final int n = scanner.nextInt();
		String[]time = new String[2];
		int[][] time1 = new int[2][6];
		time[0] = scanner.next();
		time1[0][0] = Integer.parseInt(time[0].substring(0, 4));
		time1[0][1] = Integer.parseInt(time[0].substring(4, 6));
		time1[0][2] = Integer.parseInt(time[0].substring(6, 8));
		time1[0][3] = Integer.parseInt(time[0].substring(8, 10));
		time1[0][4] = Integer.parseInt(time[0].substring(10, 12));
		time[1] = scanner.next();
		time1[1][0] = Integer.parseInt(time[1].substring(0, 4));
		time1[1][1] = Integer.parseInt(time[1].substring(4, 6));
		time1[1][2] = Integer.parseInt(time[1].substring(6, 8));
		time1[1][3] = Integer.parseInt(time[1].substring(8, 10));
		time1[1][4] = Integer.parseInt(time[1].substring(10, 12));
		String[][] commond = new String[n][6];
		scanner.nextLine();
		for (int i = 0; i < n; ++i) { 
			tmp = scanner.nextLine(); 
			commond[i] = tmp.toLowerCase()
					.replaceAll("sun", "0") 
					.replaceAll("mon", "1") 
					.replaceAll("tue", "2") 
					.replaceAll("wed", "3").replaceAll("thu", "4").replaceAll("fri", "5").replaceAll("sat", "6")
					.replaceAll("jan", "1").replaceAll("feb", "2").replaceAll("mar", "3").replaceAll("apr", "4")
					.replaceAll("may", "5").replaceAll("jun", "6").replaceAll("jul", "7").replaceAll("aug", "8")
					.replaceAll("sep", "9").replaceAll("oct", "10").replaceAll("nov", "11").replaceAll("dec", "12")
					.split(" ");
			commond[i][5] = tmp.split(" ")[5];
		}
		scanner.close();
		Map<Integer, Integer> month = new HashMap<>();
		month.put(1, 31);
		month.put(2, 28);
		month.put(3, 31);
		month.put(4, 30);
		month.put(5, 31);
		month.put(6, 30);
		month.put(7, 31);
		month.put(8, 31);
		month.put(9, 30);
		month.put(10, 31);
		month.put(11, 30);
		month.put(12, 31);
		while (true) {
			// 和规则进行比较 判断顺序:月、日、星期、小时、分钟
			for (int i = 0; i < n; ++i) {
				if (!caculateMDH(i, commond, time1,3,1)) {
					continue;
				}
				if (!caculateMDH(i, commond, time1,2,2)) {
					continue;
				}
				if (!caculateMDH(i, commond, time1,4,5)) {
					continue;
				}
				if (!caculateMDH(i, commond, time1,1,3)) {
					continue;
				}
				caculateMi(i, commond, time1);
			}

			// 加1分钟
			if (++time1[0][4] >= 60) {
				time1[0][4] = time1[0][4] % 60;
				if (++time1[0][3] >= 24) {
					time1[0][3] = time1[0][3] % 24;
					if (isLeap(time1[0][0]) && 2 == time1[0][1]) {
						if (++time1[0][2] > 29) {
							time1[0][2] = time1[0][2] % 29;
							if (++time1[0][1] > 12) {
								time1[0][1] = time1[0][1] % 12;
								++time1[0][0];
							}
						}
					} else {
						if (++time1[0][2] > month.get(time1[0][1])) {
							time1[0][2] = time1[0][2] % month.get(time1[0][1]);
							if (++time1[0][1] > 12) {
								time1[0][1] = time1[0][1] % 12;
								++time1[0][0];
							}
						}
					}
				}
			}
			// 判断是否超过第二个
			if (time1[0][0] == time1[1][0] && time1[0][1] == time1[1][1] && time1[0][2] == time1[1][2]
					&& time1[0][3] == time1[1][3] && time1[0][4] == time1[1][4]) {
				break;
			}
		}
	}

	// 判断是否为闰年
	static public boolean isLeap(int year) {
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			return true;
		}
		return false;
	}
	// 判断是否为数字
	static public boolean isDig(String s) {
		for (int i = 0; i < s.length(); ++i) {
			char c = s.charAt(i);
			if (!Character.isDigit(c)) {
				return false;
			}
		}
		return true;
	}

	// 计算月/日/小时/星期
	static public boolean caculateMDH(int i, String[][] commond, int[][] time1,int c,int t) {
		if (t==5) {
			time1[0][t]= changeWeek(time1[0][0], time1[0][1], time1[0][2]);
		}
		if (isDig(commond[i][c])) {
			if (Integer.parseInt(commond[i][c]) == time1[0][t]) {
				return true;
			}
		} else if ("*".equals(commond[i][c])) {
			return true;
		} else {
			if (commond[i][c].indexOf(',') != -1) {
				string = commond[i][c].split(",");
				for (int j = 0; j < string.length; ++j) {
					if (string[j].indexOf('-') != -1) {
						a = string[j].split("-");
						if (time1[0][t] >= Integer.parseInt(a[0]) && time1[0][t] <= Integer.parseInt(a[1])) {
							return true;
						}
					} else {
						if (Integer.parseInt(string[j]) == time1[0][t]) {
							return true;
						}
					}
				}
			} else {
				String[] a = commond[i][c].split("-");
				if (time1[0][t] >= Integer.parseInt(a[0]) && time1[0][t] <= Integer.parseInt(a[1])) {
					return true;
				}
			}
		}
		return false;
	}
	// 分钟
	static public void caculateMi(int i, String[][] commond, int[][] time1) {
		if (isDig(commond[i][0])) {
			if (Integer.parseInt(commond[i][0]) == time1[0][4]) {
				System.out.printf("%4d%02d%02d%02d%02d %s", time1[0][0], time1[0][1], time1[0][2], time1[0][3],
						time1[0][4], commond[i][5]);
				System.out.println();
			}
		} else if ("*".equals(commond[i][0])) {
			System.out.printf("%4d%02d%02d%02d%02d %s", time1[0][0], time1[0][1], time1[0][2], time1[0][3], time1[0][4],
					commond[i][5]);
			System.out.println();
		} else {
			if (commond[i][0].indexOf(',') != -1) {
				string = commond[i][0].split(",");
				for (int j = 0; j < string.length; ++j) {
					if (string[j].indexOf('-') != -1) {
						a = string[j].split("-");
						if (time1[0][4] >= Integer.parseInt(a[0]) && time1[0][4] <= Integer.parseInt(a[1])) {
							System.out.printf("%4d%02d%02d%02d%02d %s", time1[0][0], time1[0][1], time1[0][2],
									time1[0][3], time1[0][4], commond[i][5]);
							System.out.println();
							break;
						}
					} else {
						if (Integer.parseInt(string[j]) == time1[0][4]) {
							System.out.printf("%4d%02d%02d%02d%02d %s", time1[0][0], time1[0][1], time1[0][2],
									time1[0][3], time1[0][4], commond[i][5]);
							System.out.println();
							break;
						}
					}
				}
			} else {
				String[] a = commond[i][0].split("-");
				if (time1[0][4] >= Integer.parseInt(a[0]) && time1[0][4] <= Integer.parseInt(a[1])) {
					System.out.printf("%4d%02d%02d%02d%02d %s", time1[0][0], time1[0][1], time1[0][2], time1[0][3],
							time1[0][4], commond[i][5]);
					System.out.println();
				}
			}
		}
	}

	// 转换星期
	static public int changeWeek(int year, int month, int day) {
		if (month == 1 || month == 2) {
			month += 12;
			year -= 1;
		}
		c = year / 100;
		y = year % 100;
		return (y + y / 4 + c / 4 - 2 * c + 26 * (month + 1) / 10 + day - 1) % 7;
	}
}

写文章仅为交流,不为其他!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值