蓝桥杯历届赛题回顾总结

本文探讨了多种编程技巧,包括日历类的使用、全排列、动态规划、记忆化搜索等,并给出了实例代码。同时涉及了数据结构、数学问题(如黄金分割比)和游戏策略。文章还介绍了如何处理数组操作、查找错误ID、幸运数概念以及在不同场景下的最佳实践。
摘要由CSDN通过智能技术生成

2013

1第一题世界末日

日历类的方便使用

Calendar calendar=Calendar.getInstance();
for(int year=1999;year<5000;year+=100){
			calendar.set(Calendar.YEAR, year);
			calendar.set(Calendar.MONTH, 11);
			calendar.set(calendar.DAY_OF_MONTH, 31);
			if(calendar.get(calendar.DAY_OF_WEEK)==1){
				System.out.print(Calendar.DAY_OF_WEEK);
				break;	
			}
		}

其他用法
a、add方法

public abstract void add(int field,int amount)

该方法的作用是在Calendar对象中的某个字段上增加或减少一定的数值,增加是amount的值为正,减少时amount的值为负。

例如在计算一下当前时间100天以后的日期,代码如下:

Calendar c3 = Calendar.getInstance();

c3.add(Calendar.DATE, 100);

int year1 = c3.get(Calendar.YEAR);

//月份

int month1 = c3.get(Calendar.MONTH) + 1;
b、after方法

public boolean after(Object when)

该方法的作用是判断当前日期对象是否在when对象的后面,如果在when对象的后面则返回true,否则返回false。例如:

Calendar c4 = Calendar.getInstance();

c4.set(2009, 10 - 1, 10);

Calendar c5 = Calendar.getInstance();

c5.set(2010, 10 - 1, 10);

boolean b = c5.after(c4);

第三题振兴中华

在这里插入图片描述
要求跳过的路线刚好构成“从我做起振兴中华”这句话。

请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
搜索模板

public static int three(int i,int j){
		 if(i==3 || j==4) 
			 return 1;//为什么是||,因为这个题只是为了计数,到了边界就只有一个方向了,所以不用一直走下去直接加1就行了
		 int t1=three(i+1,j);
		 int t2=three(i,j+1);
		 int w=t1+t2;
		 return w;
	 }
黄金连分数

BigInteger与BigDecimal的使用
https://blog.csdn.net/weixin_42265324/article/details/88726765
根据规律写出来发现是斐波纳挈
***你的任务是:写出精确到小数点后100位精度的黄金分割值。***注意这句话程序得到的100必须是稳定的,因此循环的量大一些检验检验

错误票据

你的任务是通过编程,找出断号的ID和重号的ID。
注意输入是不定长的数组,输入方式

//题目要求输入的是不定长的数组,因此输入的方法如下
		 Scanner snScanner=new Scanner(System.in);
		 ArrayList<Integer> list=new ArrayList<Integer>();
		 int n=snScanner.nextInt();
		 snScanner.nextLine();
		 int[][] ids=new int[n][];
		 for(int i=0;i<n;i++){
			 String lineString=snScanner.nextLine();
			 String[] splitStrings=lineString.split(" ");
			 for(int j=0;j<splitStrings.length;j++){
				 list.add(Integer.parseInt(splitStrings[j]));
				 
			 }
		 }

还有就是Arraylist的使用(https://www.cnblogs.com/kungfupanda/p/7357142.html)
要注意,arraylist.get取出来不是int,要用equals

if(list.get(i).equals(list.get(i-1))){
				 c=list.get(i);
			 }
幸运数

首先从1开始写出自然数1,2,3,4,5,6,… 1 就是第一个幸运数。 我们从2这个数开始。把所有序号能被2整除的项删除,变为: 1
_ 3 _ 5 _ 7 _ 9 … 把它们缩紧,重新记序,为: 1 3 5 7 9 … 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11,
17, … 此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,…)

这个题要注意的就是数组删除的部位可以记下这个模板,2014年也有类似的题
主要就是坑位p和i的变化

while(true){
			 int p=l+1;//数字向前挪动的坑位
			 for(int i=l+1;i<n/2;i++){
				 //要删除的数不做处理
				 if((i+1)%a[l]==0){
					 
				 }
				 //不删除的数就是要挪动的
				 else {
					a[p]=a[i];
					p++;
				}
			 }
			 l++;
			 //结束条件是幸运数大于N了
			 if(a[l]>=n) break;
		 }
带分数

全排列!全排列!全排列!全排列!全排列!全排列!全排列!
一般就在check中更改模板

//全排列一个数组
	 //确定某一个排列的第K位
	 public static void f9(int[] arr,int k){
	    if(k==9){ //排到数组最后一个元素就结束
			 if(check(arr)){
				 ans++;
			 }
		 }
		 //选定第K位
		 for(int i=k;i<arr.length;i++){
			 //将第i位与第K 位进行交换
			 int t=arr[i];
			 arr[i]=arr[k];
			 arr[k]=t;
			 //移交下一层
			 f9(arr,k+1);
			 //回溯,换回来
			 t=arr[i];
			 arr[i]=arr[k];
			 arr[k]=t;
		 }
}

2014

1,第三题猜字母

快速生成字母方式

		char arr[]=new char[19];
		for(int i=0;i<19;++i){
			arr[i]=(char)('a'+i);
		}

对于数组,所有偶数往前提,忽略奇数,一个数组元素往前移的模板

while(len!=1){
			int k=0;
			//把所有的偶数往前提,忽略奇数
			for(int i=1;i<len;i+=2){
				arr1[k++]=arr1[i];
			}
			len=k;
		}
2 第六题

计算最大公约数模板

//计算两数的最大公约数
	private static int gcd(int a,int b) {
		if(b==0) return a;
		return gcd(b, a%b);
	}
	
扑克排序

还是全排列,不过全排列中数组有重复值,得到的结果肯定也有重复值
利用HashSet进行去重

static Set<String> set=new HashSet<String>();
	
	public static void f7(char[] a,int k){
		if(k==a.length){
			String s=new String(a);
			if(check(s)){
				set.add(s);
			}
		}
		for(int i=k;i<a.length;i++){
			char t=a[k];
			a[k]=a[i];
			a[i]=t;
			
			f7(a, k+1);
			
		    t=a[k];
			a[k]=a[i];
			a[i]=t;
			
		}
	}
地宫取宝

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

首先dfs搜索所有路径,计算个数

public static void fun9(int x,int y,int kh,int max1){
    	//看解析终止条件应该这样写
    	if(x==n||y==m){
    		return;
    	}
    	int cur=jz[x][y];
    	if(x==n-1&&y==m-1){//走到最后一个格子
    		if(kh==k||(kh==k-1)&&cur>max1){
    			count9++;
    			if(count9>1000000007){
    				count9%=1000000007;
    			}
    		}
    		
    	}
    	//价值大的可以拿可以不拿
    	if(jz[x][y]>max1){
    		fun9(x, y+1, kh++, jz[x][y]);
    		fun9(x+1, y, kh++, jz[x][y]);
    	}
    	//考虑拿的情况
    	fun9(x, y+1, kh, max1);
    	fun9(x+1, y, kh, max1);
    } 

但是这样时间超了
修改记忆型搜索,不是动态规划

//记忆型深度搜索
    static int[][][][] cache=new int[51][51][14][14];
    public static long dfs(int x,int y,int kh,int max1){
    	//如果cache中有记录那就直接输出记录
    	if(cache[x][y][max1-1][kh]!=-1){
    		return cache[x][y][max1-1][kh];
    	}
    	if(x==n||y==m||kh>k){
    		return 0;
    	}
    	int cur=jz[x][y];
    	int ans=0;
    	if(x==n-1&&y==m-1){
    		if(kh==k||(kh==k-1&&cur>max1))return 1;
    	}
    	
    	if(cur>max1){
    		ans+=dfs(x, y+1, kh++, cur);
    		ans+=dfs(x+1, y, kh++, cur);
    	}
    	ans+=dfs(x, y+1, kh, max1);
		ans+=dfs(x+1, y, kh, max1);
		cache[x][y][max1][kh]=ans%1000000007;
		return ans%1000000007;
    }

2015

2016

剪邮票

如何全排列二维矩阵以及连通性检查的方法

static boolean check1(int[] a){	
		//将a的这个排列映射到二维矩阵上面,全排列a就相当于排列这个二维矩阵了
		int g[][]=new int[3][4];
		for(int i=0;i<3;++i){
			for(int j=0;j<4;++j){
				if(a[i*4+j]==1) g[i][j]=1;
				else {
					g[i][j]=0;
				}
			}
		}
		
		//连通性检查,如果只有一个连通块cnt=1
		int cnt=0;
		for(int i=0;i<3;++i){
			for(int j=0;j<4;++j){
				if(g[i][j]==1){
					dfs(g,i,j);
					cnt++;
				}
			}
		}
		return cnt==1;
	}
public static void dfs(int g[][],int i,int j){
		g[i][j]=0;
		if(i-1>=0&&g[i-1][j]==1)dfs(g, i-1, j);
		if(i+1<=2&&g[i+1][j]==1)dfs(g, i+1, j);
		if(j-1>=0&&g[i][j-1]==1)dfs(g, i-1, j);
		if(i+1<=3&&g[i][j+1]==1)dfs(g, i-1, j);
	}

注意再用set去重

取球博弈

两个人玩取球的游戏。 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。 如果无法继续取球,则游戏结束。
此时,持有奇数个球的一方获胜。 如果两人都是奇数,则为平局。

假设双方都采用最聪明的取法, 第一个取球的人一定能赢吗? 试编程解决这个问题。

最聪明的做法就是试探各种结果后,只要有结果是赢那就是我赢,没有赢只有平那就是我平,都没有那就是我输

2018

最长字串

#先了解一下最长子序列,两个都是用动态规划解决的
https://blog.csdn.net/hrn1216/article/details/51534607

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值