赞
踩
目录
日期类
蓝桥杯比赛中经常出现的有关日期问题的题目,通常需要大量的代码判断日期,非常不方便。Java为我们封装好了日历类Calender省去了大量的代码编写,使用该类能够让日期问题变得十分简单~
创建Calender实例
使用 Calender 的工厂方法 :
Calender.getInstance()
获取Calender实例:
public static void main(String[] args) throws IOException { Calendar calendar = Calendar.getInstance(); }Calender类字段说明
Calender字段需要额外注意,有的字段常量值与日常使用有所区别:
上面标记为红色的字段,一定要注意与现实生活中使用的不同。
设置Calender时间
Calendar 中
set
和get
时间都是通过在参数中填入不同的字段来实现的,这里设置时间为**2001年10月23日12时12分12秒** 举例说明
public static void main(String[] args) throws IOException { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, 2001); // 月份需要注意对应!! calendar.set(Calendar.MONTH, 9); calendar.set(Calendar.DATE, 23); calendar.set(Calendar.HOUR_OF_DAY, 12); calendar.set(Calendar.MINUTE, 12); calendar.set(Calendar.SECOND, 12); }同时按照代码执行的顺序,位于后方日历的设置会覆盖前面日历的设置,就例如:
public static void main(String[] args) throws IOException { Calendar calendar = Calendar.getInstance(); // 前面修改年份的设置 calendar.set(Calendar.YEAR, 2001); calendar.set(Calendar.MONTH, 9); calendar.set(Calendar.DATE, 23); calendar.set(Calendar.HOUR_OF_DAY, 12); calendar.set(Calendar.MINUTE, 12); calendar.set(Calendar.SECOND, 12); calendar.set(Calendar.WEEK_OF_YEAR, 3); // 一个修改年份的设置 calendar.set(Calendar.YEAR,2021 ); System.out.println(calendar.getTime()); }运行出来的结果为:
Mon Jan 11 12:12:12 CST 2021
Calender获取值
public static void main(String[] args) throws IOException { Calendar calendar = Calendar.getInstance(); calendar.get (Calendar.YEAR);//年 calendar.get (Calendar.MONTH) + 1;//月 ,1月对应0,2月对应1,因此需要+1 calendar.get (Calendar.DATE);//日 calendar.get (Calendar.HOUR_OF_DAY);//时 calendar.get (Calendar.MINUTE);//分 calendar.get (Calendar.SECOND);//秒 calendar.get (Calendar.DAY_OF_WEEK);//星期,周日是1,剩下自己推算) }计算时间差(LocalDateTime)
/** * @param args 两个日期相差的天数 * 求2022-2-1到2022-3-1相差的天数 * 求两个日期的时间差(可以以天、小时、分钟、秒为单位输出) */ public static void main3(String[] args) { LocalDateTime time1 = LocalDateTime.of(2022, 2, 1, 0, 0); LocalDateTime time2 = LocalDateTime.of(2022, 3, 1, 0, 0); long result = Duration.between(time1, time2).toDays(); // 28 LocalDateTime time3 = LocalDateTime.of(2022,5,13,13,13,59,23); LocalDateTime time4= LocalDateTime.of(2022,5,14,13,13,59,23); int res = (int) Duration.between(time3,time4).toMinutes(); }遍历某段日期
/** * @param args 遍历某段日期的每一天 * * 遍历2022-01-01到2022-03-01这段日期中的每一天 * * 例题:跑步锻炼 * 正常情况下,小蓝每天跑 1 千米.如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米. * 如果同时是周一或月初,小蓝也是跑 2 千米. * 小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年 10 月 1 日周四(含). * 请问这段时间小蓝总共跑步多少千米? */ public static void main4(String[] args) { Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, 2000); c.set(Calendar.MONTH, 0); c.set(Calendar.DAY_OF_MONTH, 1); int res = 0; for(;;){ if(c.get(Calendar.DAY_OF_WEEK) == 2 || c.get(Calendar.DATE) == 1){ res += 2; }else{ res += 1; } if(c.get(Calendar.YEAR) == 2020 && c.get(Calendar.MONTH) == 9 && c.get(Calendar.DAY_OF_MONTH) == 1){ break; } c.add(Calendar.DATE, 1);//天数自增1 } System.out.println(res); } /** * 方法二:模拟 */ static int[] M = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; public void paobu() { int y = 2000, m = 1, d = 1, w = 6, ans = 0; while (y != 2020 || m != 10 || d != 1) { if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) {//判断闰年 M[2] = 29; } else { M[2] = 28;// M是全局变量 } d++; w = (w + 1) % 7;// w为0为星期天 if (d > M[m]) { d = 1; m++; } if (m > 12) { m = 1; y++; } if (d == 1 || w == 1) { ans++;// 是月初或者周一多加一次 } ans++; } // 这个循环是先加值再加日期,所以2020.10.1号的已经加上去了,但是2000.1.1没加上,所以加2 ans += 2; System.out.println(ans);// 8879 }
/** * 1999年12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即XX99年)的12月31日 * 正好是星期天?回答年份 */ public void judgeYear() { // 注意Calendar实例的获取方式 Calendar calendar = Calendar.getInstance(); for (int year = 1999; year < 10000; year += 100) { // 设置年月日 calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, 11);// 其实是12月 calendar.set(Calendar.DAY_OF_MONTH, 31); if (calendar.get(Calendar.DAY_OF_WEEK) == 1) { // sunday是第一天,所以为1时是Sunday,通过源码查看 System.out.println(year);// 2299 break; } } }判断闰年
(四年一闰 && 百年不全闰)|| 四百年又闰。
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
大数据处理
你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第 1个棋盘格放 1 粒麦子,在第 2 个棋盘格放 2 粒麦子,在第 3 个棋盘格放 4 粒麦子,在第 4 个棋盘格放 8 粒麦子,......后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有 64 格)。
国王以为他只是想要一袋麦子而已,哈哈大笑。
当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!
请你借助计算机准确地计算,到底需要多少粒麦子。
public static void main(String[] args) { BigInteger a = new BigInteger("1"); BigInteger b = new BigInteger("2"); BigInteger res = new BigInteger("1"); for (int i = 2; i <= 64; i++) { a = a.multiply(b); res = res.add(a); } System.out.println(res);//18446744073709551615 System.out.println(Integer.MAX_VALUE);//2147483647 }数列求值
给定数列 1, 1, 1, 3, 5, 9, 17,……从第 4 项开始,每项都是前 3 项的和。 求第 20190324 项的最后 4 位数字。
public static void main(String[] args) { int a = 1; int b = 1; int c = 1; int d = 0; for (int i = 4; i <= 20190324; i++) { d = a + b + c; d = d % 10000; a = b; b = c; c = d; } System.out.println(d);//4659 }
常用数学技巧和基础
快速幂
虽然可以使用Java数学包下的Math.pow方法来求出x的n次幂的值,但这个函数本身运行起来是非常耗时的;对于需要参加竞赛的,无疑会在超时的边缘徘徊,而快速幂可以通过将指数拆分成多个因数相乘的形式来简化幂运算,大大调高运算效率!
public double myPow(double x, int n) { double result = 1; long v = n;// 为了保证-n不溢出,先转换成long类型 if(v < 0) {// 如果v小于0, 求1/x的-v次方 x = 1 / x; v = -v; } while(v > 0) { if((v & 1) == 1) {//此处等价于if(v % 2 == 1) result *= x; } v >>= 1;//此处等价于v = v / 2 x *= x; } return result; }最大公约数和最小公倍数
蓝桥杯的数据量是出名的大(这个后面会体现),超时是肯定的。
背下欧几里得公式直接使用(已知效率最快求出公倍数地公式)
/** * gcd函数(欧几里得算法原理) * @return 返回值则是a和b的最大公约数 */ public static int gcd(int a,int b){ return b == 0 ? a : gcd(b,a % b); } /** * lcm函数(速求最小公倍数,原理基于gcd函数) * @return 返回值为a和b的最小公倍数 */ public static int lcm(int a, int b){ return (a * b) / gcd(a,b);//最小公倍数 = 两数之积 ÷ 两数最大公约数 }进制转换
public static void conversion(){ //n进制转为十进制 System.out.println(Integer.valueOf("1111",2));//15 System.out.println(Integer.valueOf("ffff",16));//65535 //十进制转为n进制 System.out.println(Integer.toString(128,2));//10000000 System.out.println(Integer.toString(15,16));//f }求质数
1.判断一个数是否是质数
private static boolean isPrime(int n){ int i = 2; for(i = 2;i <= Math.sqrt(n);i++){ //只要模一次是0,就不是素数 if(n % i == 0){ return false; } } return i > Math.sqrt(n);//是素数 }2.求n下有多少个质数
埃筛法
埃筛法是能够快速筛选出质数的方法之一,在众多质数筛选方法中,埃筛法虽然不是最快的方法,但绝对是最容易理解的方法。
原理:从小到大开始筛选质数,当某个数被认定为质数时,那么后面能够被该数整除的数就一定不是质数,为这些数增加一个标记,当遍历到这些被标记的数时,直接跳过即可,无需再为其执行检验是否为质数的操作,因为判断一个数是否为质数是筛选质数过程中最耗时的操作,而埃筛法则能大幅度的减少该操作的执行频率,从而提高素数筛选的效率。
public static void prime(int n) { boolean[] flag = new boolean[n + 1]; for(int i = 2; i <= n; i++) { if(flag[i]){ continue; } System.out.print(i + " "); for(int j = i; i * j <= n; j++) { flag[i * j] = true; } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。