【蓝桥真题4】练练填空就想进国赛?拿下大题才能让你真正有底气(蓝桥31日冲刺打卡)

⭐️引言⭐️

              大家好啊,我是执梗。上次出的蓝桥真题三系列受到了很多同学的喜爱,大家问了我许多关于蓝桥杯的问题,我也一一解答了。但我发现起码一半以上的同学存在一个误区——我光靠选择题能拿个省一进国赛吗?在以前这种可能性是存在的,但是现在几乎是不切实际的。因为填空题的分数只有45分,大题占剩下的105分,先不说你能否做对全部填空(压轴填空还是有一定难度),即使全对你觉得自己能稳进国赛吗?答案显而易见。虽然蓝桥的难度逐渐上升,但是前面的大题难度不高,分值也很可观,这才是我们的主菜!

⭐️往期集锦⭐️

蓝桥真题3【蓝桥真题3】蓝桥改革变难,想进国赛这些能力你可缺一不可

蓝桥真题2

【蓝桥真题2】蓝桥杯不会全排列,那就只能写10个for循环了【内附近8年真题资源】
蓝桥真题1【蓝桥真题1】这道用了7个for循环的蓝桥真题,让舍友哭着跑出考场【内附原题资源】

           💯 蓝桥31日冲刺

              蓝桥就剩一个月的冲刺时间,你是否感觉一个人前进漫无目的?是否感觉刷题没有规划,找不准正确的方向?是否感觉一个人总是容易松懈容易摆烂?是否希望能够和一群志同道合的人进行31日冲击国赛?是否缺少训练的真题资源和大佬的答疑?(活动已正式开始,暂不收人)

⭐️目录⭐️

🍋1.时间显示      

👑2.分巧克力      

🎅3.时间加法

🍅4.最小公倍数

🍭5.最少砝码

🍒6.受伤的皇后

🎽7.金额差错

🍰 8.四平方和

🚀9.刷题总结


🍋1.时间显示      

         小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取
了当前的时间,用一个整数表示,值为从 1970 年 1 月 1 日 00:00:00 到当前时
刻经过的毫秒数。
        现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要
显示出时分秒即可,毫秒也不用显示,直接舍去即可。
        给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
        具体的输入输出可以在题目链接可看。
        题目链接:时间显示
        这是去年JavaB组省赛的第一道大题,有的人一看到就来一句——卧槽!这么难?从1970年开始那得有多少毫秒?算了算了先看下一题。但是大家要想一下? 题目求的是什么?是今天的时分秒!我们不需要去关心今天是多少年多少月多少日,所以我们有下面的这几步思考步骤:
         设接收到的总毫秒数为n。
         1.首先先n=n/1000。因为n的单位是毫秒,我们需要的最低精准单位是秒,而1s=1000ms,所以不足一秒的毫秒我们直接舍去,此时n的单位变成了秒
        2.进行操作n=n%(60*60*24)。因为我们只关心今天走了的时间,也就是今天走了多少秒,我们对一整天的秒数进行取余,则获得的就是未满一天的秒数,也就是今天的
        3.long hour=n/3600;因为我们已经获得了今天的秒数,1h=3600s,我们算出n可以整除出多少个3600,则就是多少个小时,由此得到了今天的小时数。
        4.n%=3600;long month=n/60;我们先对n%3600是为了得到剩下未满一个小时的秒数,也就是分加上秒的,我们对n取余60,就能得到分钟的值。
        5.n%=60; long s=n;同理于分,先取余60,剩下的n就是我们最后的秒数了。
        代码转换:
import java.util.Scanner;

public class 时间显示 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long n=sc.nextLong();
		//拿到的是毫秒,先转换为秒,1m等于1000ms
		n=n/1000;
		//现在拿到的是秒,对一天的秒数取余即可获得今天的秒数
		n=n%(60*60*24);
		//现在拿到的是一天的秒数,开始转化为答案,一小时有3600秒,先获得秒
		long hour=n/3600;
		//现在获得分钟加分
		n%=3600;
		//再获得分钟
		long month=n/60;
		//再获得秒
		n%=60;
		long s=n;
		//这里涉及输出格式,大家可以学习一下printf的输出格式
		System.out.printf("%02d:%02d:%02d",hour,month,s);	
	}
}

  👑2.分巧克力      

儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 N 块巧克力,其中第 i 块是 Hi​×Wi 的方格组成的长方形。为了公平起见,

小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数;

  2. 大小相同;

例如一块 6x5 的巧克力可以切出 6 块 2x2 的巧克力或者 2 块 3x3 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

具体的输入输出可以在题目链接可看。

题目链接:分巧克力       

        首先对于一块Hi​×Wi的巧克力,如果我们设切出的巧克力边长为n(题目要求必须是正方形),那么这块巧克力能切出我们符合要求的巧克力的块数为(Hi/n​)​×(Wi/n)。一个小破图给大家理解一下。
        
        这个公式对于每块巧克力都是适用的。也就是说,当我们选定一个n,就可以计算出这一堆巧克力能切出多少块边长为n的巧克力。我们需要去找出最大的符合条件的n,很明显,我们需要引用到二分查找——去找到最大的符合条件的n,这里的符合条件是保证切出的块数大于等于K,也就是足够每个小朋友分到。
        代码转换:
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int N=sc.nextInt();
		int K=sc.nextInt();
        //用来存储每块巧克力的长和宽
		int[][] arr=new int[N][2];
		for(int i=0;i<N;++i) {
			arr[i][0]=sc.nextInt();
			arr[i][1]=sc.nextInt();
		}
        //r的值根据题目给的长和宽进行选择
		int l=1;
		int r=100000;
		while(l<r) {
			int mid=(l+r+1)/2;
            //check满足说明切的块数足够分
			if(check(arr,mid,K)) l=mid;
			else r=mid-1;
		}
		System.out.println(l);
	}
	//X越小块数越多,找出X的最大值
	//判断以边长X来分,是否可以分够X块
	static boolean check(int[][] arr,int X,int K) {
		int count=0;
		for(int i=0;i<arr.length;++i) {
            //这里计算能分多少块边长为X的巧克力
			int ans=(arr[i][0]/X)*(arr[i][1]/X);
			count+=ans;
		}
		return count>=K;
	}
}	

 🎅3.时间加法

现在时间是 a 点 b 分,请问 t 分钟后,是几点几分?

题目链接:时间加法

具体的输入输出可以在题目链接可看。

          这是今年一道简单的模拟赛题目,我们需要模拟时间的加法,这里需要完成分钟超过60后对小时进行进位,小时超过24小时后需要重置(也就是到达了第二天)
         代码转换:
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int a=sc.nextInt();
		int b=sc.nextInt();
		int t=sc.nextInt();
        //让分钟加上t
		b+=t;
		int ans=0;
        //如果分钟达到60,需要进位
		if(b>=60) {
            //算出小时的增量
			ans=b/60;
            //对60取余算出分钟
			b%=60;
		}
        //小时加上增量
		a+=ans;
		if(a>=24) {
            //如果小时超过24需要取余重置
			a%=24;
		}
		System.out.println(a);
		System.out.println(b);
	}
}

🍅4.最小公倍数

为什么 1 小时有 60 分钟,而不是 100 分钟呢?这是历史上的习惯导致。

但也并非纯粹的偶然:60 是个优秀的数字,它的因子比较多。

事实上,它是 1 至 6 的每个数字的倍数。即 1,2,3,4,5,6 都是可以除尽 60。

我们希望寻找到能除尽 1 至 nn 的的每个数字的最小整数。

不要小看这个数字,它可能十分大,比如 nn = 100, 则该数为:

69720375229712477164533808935312303556800

输入一个数字 N(N<100)。

题目链接:最小公倍数        

        这道题很明显考察的是大数,关于大树我在蓝桥真题三中的棋盘放麦子也讲过。用long可以算到大概N=50。但是超过50后就会爆long,所以在Java中需要使用BigInteger这个类。同时使用gcd和lcm公式(这也在蓝桥真题三中讲过)。值得一提的是,大数的考察一般是在国赛,大家视情况是否学习。当然也可以使用数组模拟加法,这也是一个非常不错的方法。
import java.math.BigInteger;
import java.util.Scanner;

public class 最小公倍数 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		BigInteger a=new BigInteger("1");
		BigInteger b=new BigInteger("2");
		BigInteger c=new BigInteger("1");
		int ans=2;
		while(ans<=n) {
			a=lcm(a,b);
			b=b.add(c);
			ans++;
		}
		System.out.println(a);
	}
	static BigInteger gcd(BigInteger a,BigInteger b) {
		return b.toString().equals("0")?a:gcd(b,a.mod(b));
	}
	
	static BigInteger lcm(BigInteger a,BigInteger b) {
		return a.divide(gcd(a,b)).multiply(b);
	}
}

🍭5.最少砝码

你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 NN 的正整数重量。

那么这套砝码最少需要包含多少个砝码?

注意砝码可以放在天平两边。

题目链接:最少砝码       

        这是2021年的省赛真题,需要运用到贪心思想。我们来分析前几步选择:
         1.首先表示1这个数,我们只能用1这个砝码,此时砝码个数为1。这一步很容易思考。
        2.这时考虑表示2这个数,我们难道选两个1吗?这就涉及到贪心思想了,为了尽可能表示更大的数,这时候我们选用砝码3,这样3-1=2,3+1=4。我们能同时表示1,2,3,4这四个数,此时砝码有1,3,砝码个数为2。
       3.这时我们需要考虑如何表示5这个数。还是利用贪心思想,我们此时能表达的最大数是4,为了表达5且使用更大的砝码,我们选择9这个砝码,因为9-3-1=5。这时候我们能表达的最大数是多少呢?理所当然是1+3+9=13。那么问题来了?[6,12]我们能表达出来吗?
        我们尝试一下:
        9-3=6;
        9-3+1=7;
        9-1=8;
        9=9;
        9+1=10;
        9+3-1=11;
        9+3=12;
     我们发现这个区间的数是可以完全表达出来的,到这我相信你也一个大胆的猜想。我们让初始砝码数count=1,初始可表达最大值ans=1。每当count++,ans的范围将会变为2*ans+1。这里我通过一个简图给大家看看:

      我们只需要一直按照这个规律推算ans的值,当ans>=题目要求的N,说明此时的count就是我们的答案。

        代码转换:(看着非常简洁,主要是找出规律)

import java.util.Scanner;

public class 最少砝码 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		//刚开始的砝码
		int count=1;
		//表示最大称重
		int ans=1;
		while(ans<n) {
			count++;
			ans+=(ans+1+ans);
		}
		System.out.println(count);
	}
}

🍒6.受伤的皇后

有一个n×n 的国际象棋棋盘(n 行 n 列的方格图),请在棋盘中摆放 n 个受伤的国际象棋皇后,要求:

  1. 任何两个皇后不在同一行。
  2. 任何两个皇后不在同一列。
  3. 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。

请问一共有多少种摆放方案。

题目链接:受伤的皇后        

        这道题目有的同学可能觉得眼熟,别眼熟了。这道题就算力扣原题,几乎一模一样,只是力扣的题目没有行号差值限制,给上链接。吃透N皇后问题,很有必要。
       力扣N皇后链接: N皇后
        代码转换:
import java.util.Arrays;
import java.util.Scanner;

public class 受伤的皇后 {
	static int ans=0;
	static char[][] arr;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		arr=new char[n][n];
		for(char[] a:arr) {
			Arrays.fill(a,'.');
		}
		dfs(n,0);
		System.out.println(ans);
	}
		
	static void dfs(int n,int row){
		if(row==n) {
			ans++;
			return;
		}
		for(int col=0;col<n;++col) {
			if(check(n,row,col)) {
				arr[row][col]='Q';
				dfs(n,row+1);
				arr[row][col]='.';
			}
		}
	}
	//row是行,col是列
	static boolean check(int n,int row,int col) {
		//判断列
		for(int i=0;i<row;++i){
			if(arr[i][col]=='Q') return false;
		}
		//判断45度角
		int a=1;
		for(int i=row-1,j=col-1;a<=2&&i>=0&&j>=0;a++,j--,i--) {
			if(arr[i][j]=='Q') return false;
		}
		a=1;
		for(int i=row-1,j=col+1;a<=2&&i>=0&&j<n;a++,i--,j++) {
			if(arr[i][j]=='Q') return false;
		}
		
		return true;
	}
}

🎽7.金额差错

某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某 1 笔或几笔。如果已知明细账目清单,能通过编程找到漏掉的是哪 1 笔或几笔吗?

如果有多种可能,则输出所有可能的情况。

题目链接:金额查错

      经典的组合问题,我们先要计算出差了多少金额target,然后从所有的子序列中找出和为target的所有组合。难点在于去重,因为这题是不允许出现一模一样的组合(虽然题目没说,但从它给的例子是可以看出来的)。像这样题目有Set去重和排序去重两种方法,效率更好的方法是排序去重,因为排序可以减枝。这道题力扣也有类似原题,我会附上地址
      力扣类似题: 组合总和||
      代码转换:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {
	static List<Integer> path=new ArrayList();
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		//错误的金额
		int count=sc.nextInt();
		int n=sc.nextInt();
		int[] arr=new int[n];
		//计算正确的金额
		int ans=0;
		for(int i=0;i<n;++i) {
			arr[i]=sc.nextInt();
			ans+=arr[i];
		}
		int target=ans-count;
		Arrays.sort(arr);
		dfs(arr,target,0);
	}
	
	static void dfs(int[] arr,int target,int start) {
        //剪枝
		if(target<0) return;
		if(target==0) {
			for(int a:path) {
				System.out.print(a+" ");
			}
			System.out.println();
			return;
		}
		for(int i=start;i<arr.length;i++) {
            //去重核心代码
			if(i>start&&arr[i]==arr[i-1]) continue;
			path.add(arr[i]);
			dfs(arr,target-arr[i],i+1);
			path.remove(path.size()-1);
		}
	}
}

🍰 8.四平方和

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多 44 个正整数的平方和。

如果把 00 包括进去,就正好可以表示为 44 个数的平方和。

比如:

5=0^2+0^2+1^2+2^2
7=1^2+1^2+1^2+2^2

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对 4 个数排序:

0≤a≤b≤c≤d

并对所有的可能表示法按 a,b,c,d为联合主键升序排列,最后输出第一个表示法。

题目链接:四平方和

        这道题目是往年一道非常非常经典的题目,在ABC组它都出现了。它有二分和哈希两种做法,哈希的做法更易于理解,所以我在这讲解哈希的做法。
        首先这里出现了4个数字a,b,c,d。我们能去通过循环去模拟四位数的情况吗?当然不行,这样的时间复杂度为O(n^3),当然因为这是大题,实习想不到方法这样写也是可以过一些案例得一些分数。考虑到这种情况,我们应该就这个字母分为两组,ab为一组,cd为一组,这样分别枚举的话时间复杂度可以降到O(n^2)。先将某一组的所有的组合情况枚举放到Map集合中,然后枚举另外一对组合的情况,每次判断Map中是否有值让两者相加等于我们的N。
         这时有一个问题——我们是把ab组合的值放入到map还是cd?
   答案是CD。因为题目要求的输出方式是升序且保证a≤b≤c≤d,我们要尽可能让a和b小。所以我们把cd组合的值放到Map中,去从小到大枚举ab,只要找到Map存在符合的值,此时就是我们的答案。
        因为Map中的key是c^2+d^2的值,Value需要同时能记录c和d,所以我们需要一个Node节点能同时记录c和d的值。这样枚举到符合的情况时,我们可以同时取出c和d。
        代码转换:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
	static Map<Integer,Node> map=new HashMap<>();
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
        //注意abcd枚举时的判断条件
		for(int c=0;c*c<=n;++c) {
			for(int d=c;d*d+c*c<=n;d++) {
				int t=c*c+d*d;
				if(!map.containsKey(t)) {
					map.put(t, new Node(c,d));
				}
			}
		}
		for(int a=0;a*a<=n;++a) {
			for(int b=a;a*a+b*b<=n;++b) {
				int ans=n-a*a-b*b;
				if(map.containsKey(ans)) {
					System.out.println(a+" "+b+" "+map.get(ans).c+" "+map.get(ans).d);
					return;
				}
			}
		}
		
	}
}
//同时存入c和d
class Node{
	int c,d;
	public Node(int c,int d) {
		this.c=c;
		this.d=d;
	}
}

🚀9.刷题总结

       这次出的大题难度还是不算高,甚至很多都是模板题,大家如果能在掌握填空题的基础上,掌握好这些基础的大题,进国赛的可能性是非常非常大的。希望大家能够持之以恒,对于题目有任何的疑问,都可以在评论区提出一起交流。 

        如果有用还希望兄弟们能三连支持一下!!感谢

  • 245
    点赞
  • 912
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 162
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 162
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执 梗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值