⛄️2.4猜生日
今年的植树节(2012 年 3 月 12 日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”
“把我出生的年月日连起来拼成一个 8位数(月、日不足两位前补 0)正好可以被今天的年、月、日整除!”
他想了想,又补充到:“再给个提示,我是 6 月出生的。”
根据这些信息,请你帮小明算一下,他叔叔的出生年月日。
格式是年月日连成的 8 位数。例如,如果是 1948 年 6 月 12 日,就写:19480612。
题目链接:猜生日https://www.lanqiao.cn/problems/738/learning/
这道题表面上考的和日期有关,但已经告诉了我们月份了,难度大大降低,根本不用去考虑闰年平年有关二月份的问题,考的只是普通的模拟而已。
public class 猜生日 { static int a=2012; static int b=3; static int c=12; public static void main(String[] args) { for(int i=1900;i<2000;i++){ for(int j=1;j<=30;j++){ long count=i*10000+600+j; //同时是年月份的倍数则是答案 if(count%2012==0&&count%3==0&&count%12==0){ System.out.println(count);//19550604 } } } } }
🍋3.超大数据处理问题
这也是蓝桥杯的一大特色,无论是填空题还是大题,数据范围都大的离谱。填空题用int必爆,大题用int拿不到满分。所以对于大数据的处理问题,是非常重要的一项能力,通过真题我们来看看就找到了
⚡️3.1棋盘放麦子
你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第 1个棋盘格放 1 粒麦子,在第 2 个棋盘格放 2 粒麦子,在第 3 个棋盘格放 4 粒麦子,在第 4 个棋盘格放 8 粒麦子,......后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有 64 格)。
国王以为他只是想要一袋麦子而已,哈哈大笑。
当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!
请你借助计算机准确地计算,到底需要多少粒麦子。
题目链接:棋盘放麦子https://www.lanqiao.cn/problems/739/learning/
题目都说全世界都铺满麦子都不敢用,那我们可想而知这个数是有多大!int肯定是不行,用long去计算肯定也是同样的结果——会爆掉!这时候理所当然地去想究竟还能不能表示出比long更大地值?既然题目这样问了,那肯定是有的,那就是——BigInteegr。这个类相信很多人都没有用过,因为确实大部分的题目long已经够用了。这个类比较麻烦,因为加减乘除都需要通过方法去完成,这里大家可以去查API文档使用它。大家可以看看这个数究竟有多大!
public class 棋盘放麦子 { public static void main(String[] args) { BigInteger count=new BigInteger("1"); BigInteger ans=new BigInteger("1"); BigInteger x=new BigInteger("2"); for(int i=2;i<=64;i++){ ans=ans.multiply(x); count=count.add(ans); } System.out.println(count);//18446744073709551615 } }
🌀3.2数列求值
给定数列 1, 1, 1, 3, 5, 9, 17,……从第 4 项开始,每项都是前 3 项的和。
求第 20190324 项的最后 4 位数字。
题目链接:数列求值https://www.lanqiao.cn/problems/600/learning/
这道题的目的并不是要让大家去用什么大数据类型处理,要去分析题意!这个数之大肯定是无法用数字表示的,而题目只要求我们最后4位数字——更加说明所以这道题根本不需要去大数据处理!题目只关心最后四位数字,而前面的数字根部不会影响后面的数字,所以当我们的数字大于4位数时,我们只保留它的后四位即可。
public class 数列求值 { 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; if(d>10000) d=check(d); a=b; b=c; c=d; } System.out.println(d);//4659 } static int check(int n){ return n%10000; } }
🍏 4.打表模拟能力
之所以说打表能力是重中之重,是因为掌握好它,不仅能快速算出答案节省出我们很多的时间,对于许多题目还能化繁为简。之所以能如此,是因为蓝桥的填空题只需要答案,哪怕你写的程序要跑个几分钟才能跑出答案,那有如何?只要我的答案是对的,而且一般打表最多也就十几秒钟,想要进国赛?不会打表那可不行!光说不练肯定无用!直接上题
🌊4.1算式问题
看这个算式:
☆☆☆ + ☆☆☆ = ☆☆☆
如果每个五角星代表 1 ~ 9 的不同的数字。
这个算式有多少种可能的正确填写方法?
题目链接:算式问题https://www.lanqiao.cn/problems/731/learning/
这道题很简单,考的就是全排列,全排列的重要性不言而喻,在算法真题1中我出了各种详细真题,还不会的小伙伴们一定要掌握!首先给出模板全排列做法。test方法是固定全排列模板方法,check的逻辑根据题目要求来写。
public class 算式问题 { static int[] arr= {1,2,3,4,5,6,7,8,9}; static int ans=0; public static void main(String[] args) { test(0); System.out.println(ans);//336 } static void test(int k) { if(k==9) { if(check()) ans++; return; } for(int i=k;i<arr.length;i++) { exch(k,i); test(k+1); exch(k,i); } } static boolean check() { int a=arr[0]*100+arr[1]*10+arr[2]; int b=arr[3]*100+arr[4]*10+arr[5]; int c=arr[6]*100+arr[7]*10+arr[8]; return a+b==c; } static void exch(int a,int b) { int tmp=arr[a]; arr[a]=arr[b]; arr[b]=tmp; } }
有的兄弟说,万一全排列没记住咋办??没办法了,那只能打表了,去模拟所有的三位数加法情况,再去判断是否满足九个数不相等。代码量还是有点大,但是考场上做不出来也只能如此了。
我们把A从123到987进行模拟,因为123是满足题目要求的最小数字,987是满足题目要求的最大数字,则B应该对于为(123到987)-A。然后A+B得到一个C,再去判断是否满足九个数不相等。
import java.util.Map; import java.util.Scanner; import java.util.TreeMap; public class Main { static int check(int a, int b, int c) { int flag[]=new int[11]; for(int i=0;i<10;i++) flag[i]=0; flag[0]=1; while(a!=0) { if(flag[a%10]==1) return 0; else flag[a%10]=1; if(flag[b%10]==1) return 0; else flag[b%10]=1 ; if(flag[c%10]==1) return 0; else flag[c%10]=1 ; a=a/10; b=b/10; c=c/10; } return 1; } public static void main(String[] args) { int ans=0; for(int a=123;a<=987;a++) for(int b=123;b<=987-a;b++) { int c=a+b; if(check(a,b,c)==1) { ans++; System.out.println(a+"+"+b+"="+c); } } System.out.println(ans); } }
🌊 4.2求值
学习了约数后,小明对于约数很好奇,他发现,给定一个正整数 tt,总是可以找到含有 tt 个约数的整数。小明对于含有 tt 个约数的最小数非常感兴趣,并把它定义为 S_tSt 。
例如 S1 = 1, S2 = 2, S3 = 4, S4 = 6,· · ·S1=1,S2=2,S3=4,S4=6,⋅⋅⋅ 。
现在小明想知道,当 t=100 时,St100是多少?即 S100 是多少?
题目链接:求值https://www.lanqiao.cn/courses/3993/learning/?id=250188
题目的要求就是找一个最小的有100个因数的数,我们写一个计算因数个数的方法,然后从1开始往后遍历即可。这里推荐大家计算因数个数的方法不要去优化,防止一些细节出问题,数据量不大,从1遍历到n就好。我们的目的是为了得到正确答案,在可以的情况下,尽量不优化代码防止出错。
public class 求值 { public static void main(String[] args) { int count=1; //在到达1000000前肯定能得到答案的 for(;count<=1000000;count++) { if(check(count)==100) break; } System.out.println(count);//45360 } static int check(int n) { int ans=0; //朴素遍历无需优化 for(int i=1;i<=n;i++) { if(n%i==0) ans++; } return ans; } }