蓝桥杯 2017-7 日期问题

我去,终于过了,没啥算法水准的题,我花了一个半小时才调试通过!!!!!!!!!!!
题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入:
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输入:
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入:
02/03/04
样例输出:
2002-03-04
2004-02-03
2004-03-02

这个题一看就是模拟题,先判断,再打印,没啥烧脑的地方。但是我还是犯了不少错误。
首先,因为他要考虑的东西太多了,就考虑了复杂的,遗漏了最简单的东西。

private static boolean f(int year, int mouth, int day) {
		// TODO Auto-generated method stub
		if (mouth == 0 || day == 0 || mouth > 12) {
			return false;
		}
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
			if (mouth == 2) {
				if (day < 30) {
					return true;
				}
			} else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10
					|| mouth == 12) {
				if (day < 32) {
					return true;
				}
			} else {
				if (day < 31) {
					return true;
				}
			}
		} else {
			if (mouth == 2) {
				if (day < 29) {
					return true;
				}
			} else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10
					|| mouth == 12) {
				if (day < 32) {
					return true;
				}
			} else {
				if (day < 31) {
					return true;
				}
			}
		}
		return false;
	}

就是在这里,我考虑了闰年的时候二月份的天数问题,但是我一开始没有考虑月份不能大于12,还有因为有2000年,会出现00,所以也没有考虑月份和天数要大于0.也就是下面的代码我一开始没有,

if (mouth == 0 || day == 0 || mouth > 12) {
			return false;
		}

第二,排序问题。原题要求按日期从早到晚排列。但是我给忘了这回事了。最后决定用字符串的哈希值,直接用了sort函数排序。

Arrays.sort(ss, 0, j);
		System.out.println(ss[0]);
		for (int i = 1; i < j; i++) {
			if (!ss[i].equals(ss[i - 1]))
				System.out.println(ss[i]);
		}

这里又有两个问题了,一开始我申请的数组是s,发现我上面有s了,就改成ss了,但是sort那里忘了改,就一直不对,我以为是字符串排序的问题,我决定改用整数,就在改的过程中发现了我的错误,最终还是决定用字符串。
然后,会有重复的。就比如02/02/02,无论年月日还是日月年都是2002-02-02,这样会多打印,所以要判断重复。其实这里字符串改成set也行,就不会有重复问题,也不会有后面的问题。ss数组不一定全都有值,我一开始写Arrays.sort(ss);,编译无法通过,会有空指针问题。
还有一个很无语的错误,int year = a[i] + 1900;一开始写成int year = a[i] + 1000;了。
就是这些问题。唉。。。。。。

import java.util.Arrays;
import java.util.Scanner;

public class okt7日期问题 {
	// 有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的
	// 1960年1月1日至2059年12月31日
	static int[] a = new int[3];

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String string = scanner.next();
		String[] s = string.split("/");

		a[0] = Integer.parseInt(s[0]);
		a[1] = Integer.parseInt(s[1]);
		a[2] = Integer.parseInt(s[2]);
		String[] ss = new String[3];
		int j = 0;
		if (check(0, 1, 2)) {
			ss[j++] = print(0, 1, 2);
		}
		if (check(2, 0, 1)) {
			ss[j++] = print(2, 0, 1);
		}
		if (check(2, 1, 0)) {
			ss[j++] = print(2, 1, 0);
		}
		Arrays.sort(ss, 0, j);
		System.out.println(ss[0]);
		for (int i = 1; i < j; i++) {
			if (!ss[i].equals(ss[i - 1]))
				System.out.println(ss[i]);
		}
	}

	private static String print(int i, int j, int k) {
		if (a[i] < 60) {
			int year = a[i] + 2000;
			int mouth = a[j];
			int day = a[k];
			String dayString = day + "";
			String mouthString = mouth + "";
			if (day < 10) {
				dayString = "0" + dayString;
			}
			if (mouth < 10) {
				mouthString = "0" + mouthString;
			}
			return year + "-" + mouthString + "-" + dayString;

		} else {
			int year = a[i] + 1900;
			int mouth = a[j];
			int day = a[k];
			String dayString = day + "";
			String mouthString = mouth + "";
			if (day < 10) {
				dayString = "0" + dayString;
			}
			if (mouth < 10) {
				mouthString = "0" + mouthString;
			}
			return year + "-" + mouthString + "-" + dayString;
		}
	}

	// 月/日/年
	private static boolean check(int i, int j, int k) {
		if (a[i] < 60) {
			int year = a[i] + 2000;
			int mouth = a[j];
			int day = a[k];
			return f(year, mouth, day);

		} else {
			int year = a[i] + 1900;
			int mouth = a[j];
			int day = a[k];
			return f(year, mouth, day);
		}
	}

	private static boolean f(int year, int mouth, int day) {
		if (mouth == 0 || day == 0 || mouth > 12) {
			return false;
		}
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
			if (mouth == 2) {
				if (day < 30) {
					return true;
				}
			} else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10
					|| mouth == 12) {
				if (day < 32) {
					return true;
				}
			} else {
				if (day < 31) {
					return true;
				}
			}
		} else {
			if (mouth == 2) {
				if (day < 29) {
					return true;
				}
			} else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10
					|| mouth == 12) {
				if (day < 32) {
					return true;
				}
			} else {
				if (day < 31) {
					return true;
				}
			}
		}
		return false;
	}
}

这个代码量有点多,我就找了找其它大神的代码,然后,,,膜拜!!!!!!!!!
下面是参照大佬的代码写的

import java.util.Scanner;

public class tt {
	// 有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的
	static int[] a = new int[3];
	static int[] map = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String string = scanner.next();
		String[] s = string.split("/");
		a[0] = Integer.parseInt(s[0]);
		a[1] = Integer.parseInt(s[1]);
		a[2] = Integer.parseInt(s[2]);
		for (int data = 19600000; data < 20591232; data++) {
			int year = data / 10000;
			int mouth = data % 10000 / 100;
			int day = data % 100;
			if (check(year, mouth, day)) {
				if ((year % 100 == a[0] && mouth == a[1] && day == a[2])
						|| (year % 100 == a[2] && mouth == a[0] && day == a[1])
						|| (year % 100 == a[2] && mouth == a[1] && day == a[0])) {
					if (mouth < 10 && day < 10) {
						System.out.println(year + "-" + "0" + mouth + "-" + "0" + day);
					} else if (mouth < 10) {
						System.out.println(year + "-" + "0" + mouth + "-" + day);
					} else if (day < 10) {
						System.out.println(year + "-" + mouth + "-" + "0" + day);
					} else {
						System.out.println(year + "-" + mouth + "-" + day);
					}

				}
			}
		}
	}

	private static boolean check(int year, int mouth, int day) {
		if (mouth > 12 || mouth == 0 || day == 0) {
			return false;
		}
		if (mouth != 2) {
			if (day > map[mouth - 1]) {
				return false;
			}
		}
		if (mouth == 2) {
			if ((year % 4 == 0 && year % 100 != 0) || year % 100 == 0) {
				if (day > 29) {
					return false;
				}
			} else {
				if (day > 28) {
					return false;
				}
			}
		}
		return true;
	}
}

其实还可以再简单些,本着已经和它耗了这么长时间,不在乎再耗点的精神,我决定再简单些。
格式化字符串输出
链接
链接

import java.util.Scanner;

public class tt {
	// 有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的
	static int[] a = new int[3];
	static int[] map = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String string = scanner.next();
		String[] s = string.split("/");
		a[0] = Integer.parseInt(s[0]);
		a[1] = Integer.parseInt(s[1]);
		a[2] = Integer.parseInt(s[2]);
		for (int data = 19600000; data < 20591232; data++) {
			int year = data / 10000;
			int mouth = data % 10000 / 100;
			int day = data % 100;
			if (check(year, mouth, day)) {
				if ((year % 100 == a[0] && mouth == a[1] && day == a[2])
						|| (year % 100 == a[2] && mouth == a[0] && day == a[1])
						|| (year % 100 == a[2] && mouth == a[1] && day == a[0])) {
					System.out.println(year + "-" + String.format("%02d", mouth) + "-" + String.format("%02d", day));
				}
			}
		}
	}

	private static boolean check(int year, int mouth, int day) {
		if (mouth > 12 || mouth == 0 || day == 0) {
			return false;
		}
		if (mouth != 2) {
			if (day > map[mouth - 1]) {
				return false;
			}
		}
		if (mouth == 2) {
			int leap = 0;
			if ((year % 4 == 0 && year % 100 != 0) || year % 100 == 0) {
				leap = 1;
			}
			if (day > map[mouth - 1] + leap) {
				return false;
			}
		}
		return true;
	}
}

你可能感兴趣的:(蓝桥杯,动态规划,算法,蓝桥杯)