蓝桥杯31天冲刺 Day14

本文介绍了三道算法题目,分别是全排列解决算式900问题、贪心策略应用于谈判情景以及模拟幸运数的生成过程。通过DFS实现全排列,检查并计算满足条件的算式;谈判问题采用贪心思想,按人数从小到大合并村庄以减少合并次数;幸运数模拟中,通过迭代删除幸运数并计数,最终输出结果。

蓝桥杯31天冲刺 Day14

算式900

链接: 算式900.
在这里插入图片描述
这道题只要掌握最基本的全排列模板,把0~9全排列出来,问题就解决一大半了

这里,我使用int[](nums数组设置为公共常量)来存放排序好的数字,具体实现方法:

    public static void DFS(int start) {
		if(start == 9) {
			
			if(check()) {
				cal();
			}
		}
		for(int i=start;i<=9;i++) {
			swap(nums,start,i);
			DFS(start+1);
			swap(nums,start,i);
			
		}
	}
    public static void swap(int[] nums,int i ,int j) {
		int t=nums[i];
		nums[i]=nums[j];
		nums[j]=t;
	}

这里的check()函数和cal()函数后面会讲到

其中,满足全排列终止条件后(也就说明找到了一种全排列组合),我们就可以对这组数字进行进一步处理了

  • check()函数:检查三个数字是否符合规范(开头不为0)
    public static boolean check() {
		if(nums[0] == 0 ||nums[4]==0||nums[8]==0)
			return false;
		return true;
	}
  • cal()函数:进行式子的验证,将nums中的数字转换成相应数字,进行计算即可
    public static void cal() {
		int a =nums[0] * 1000 + nums[1] * 100 + nums[2] *10 + nums[3] ;
		int b =nums[4] *1000 + nums[5] * 100 +nums[6] * 10 + nums[7];
		int c = nums[8] *10 + nums[9];
		if(a>b&&(a-b) * c ==900)
			System.out.println(a+"  "+b+"  "+c);
	}

整体代码:

package 题库;
import java.util.*;

public class 算式900 {
	
	public static int[] nums = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        DFS(0);
	}
	
	public static void DFS(int start) {
		if(start == 9) {
			if(check()) {
				cal();
			}
		}
		for(int i=start;i<=9;i++) {
			swap(nums,start,i);
			DFS(start+1);
			swap(nums,start,i);
		}
	}
	
	public static void swap(int[] nums,int i ,int j) {
		int t=nums[i];
		nums[i]=nums[j];
		nums[j]=t;
	}
	
	public static void cal() {
		int a =nums[0] * 1000 + nums[1] * 100 + nums[2] *10 + nums[3] ;
		int b =nums[4] *1000 + nums[5] * 100 +nums[6] * 10 + nums[7];
		int c = nums[8] *10 + nums[9];
		if(a>b&&(a-b) * c ==900)
			System.out.println(a+"  "+b+"  "+c);
	}
	
	public static boolean check() {
		if(nums[0] == 0 ||nums[4]==0||nums[8]==0)
			return false;
		return true;
	}

}

谈判

链接: 谈判.
在这里插入图片描述
这是一个很简单的贪心思想

拿题目中的例子举例
在这里插入图片描述
题意是什么呢?谈判就是将两个村落合并,直到只剩一个村落为止。我们先按顺序来模拟一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时已经合并为了一个村落,我们再复盘一下,数一下每个村庄都花费了几次
在这里插入图片描述
这样我们可以很容易看出,把人数越少的村庄排在前面,花费越少,我们就可以很容易解决这题了

完整代码:

import java.util.*;

public class 谈判 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] nums = new int[n];
		for(int i =0;i<n;i++)
			nums[i] = sc.nextInt();
		Arrays.sort(nums);
		int res = 0;
		int j =n-1;
		for(int i =0;i<n;i++) {
			if(i==0) {
				res+=nums[i]*j;
				continue;
			}
			res+=nums[i] * j;
			j--;
		}
		System.out.println(res);

	}

}

幸运数

链接: 幸运数.
在这里插入图片描述
这道题我们直接模拟来实现

首先,我们需要建一个大小为n+1的数组,下标值也就代表对应数字值。 比如说nums[10] = 10。同时,由于数组初始化,其中填充的数字都是0,所以我们用1来表示当前位置数字已被删除。

然后,想要模拟这一过程,就要用循环来实现

我们先设立一个变量i,来表示当前的幸运数。但是,前提是,当前位置的数字得存在,我们就需要把i挪动到存在的幸运数,就有了以下代码:

        while(nums[i]!=0) {
        		i++;
        	}

然后,根据题意,从头开始数存在的数字个数,只要当前的个数%i==0,我们就要删除它,也就是将nums[j] = 1

            int cnt=0;
        	for(int j=1;j<=n;j++) {
        		if(nums[j] == 0) {
        		    cnt++;
        		if(cnt%i == 0) {
        			nums[j] = 1;
        		}

最后,我们遍历一下(m,n),数一下nums[i]==0的个数,最后输出即可

        int res = 0;
        for(int i =m+1 ;i < n ;i++ ) {
        	if(nums[i] == 0)
        		res++;
        }
        
        System.out.println(res);

整体代码:

package 题库;
import java.util.*;
public class 幸运数 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int n = sc.nextInt();
        int[] nums = new int[n+1];
        //模拟
        for(int i =2;i<=n;i++) {
        	while(nums[i]!=0) {
        		i++;
        	}
        	int cnt=0;
        	for(int j=1;j<=n;j++) {
        		if(nums[j] == 0) {
        		    cnt++;
        		if(cnt%i == 0) {
        			nums[j] = 1;
        		}
        		}
        	}
        }
        
        int res = 0;
        for(int i =m+1 ;i < n ;i++ ) {
        	if(nums[i] == 0)
        		res++;
        }
        System.out.println(res);
	}
}

### 蓝桥杯 Java 省赛一等奖备考策略 #### 明确目标与评估现状 对于希望在十内冲击蓝桥杯省赛一等奖的学生来说,首先要对自己的现有水平有一个清晰的认识。了解自己擅长的知识领域以及薄弱环节至关重要[^1]。 #### 合理规划学习时间表 制定一个紧凑但合理的时间安排非常重要。每应分配特定时间段用于理论复习、算法练习和模拟考试。确保每项活动都有足够的时间来深入理解和巩固所学内容。 #### 集中攻克核心知识点 针对Java编程语言的核心概念和技术要点进行强化训练。特别关注数据结构(如数组、链表)、基本算法设计模式(递归、贪心法),以及面向对象特性等方面的内容[^2]。 ```java // 示例:快速排序实现 public class QuickSortExample { public static void main(String[] args) { int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1}; quickSort(array); System.out.println(Arrays.toString(array)); } private static void quickSort(int[] arr) { if (arr == null || arr.length == 0){ return; } sort(arr, 0, arr.length - 1); } private static void sort(int[] a, int low, int high) { if (low >= high) { return; } int baseIndex = partition(a, low, high); sort(a, low, baseIndex - 1); // 对左侧子序列排序 sort(a, baseIndex + 1, high); // 对右侧子序列排序 } private static int partition(int[] a, int start, int end) { Random random = new Random(); swap(a, start, start + random.nextInt(end - start + 1)); int pivotValue = a[start]; while(start < end){ while((start<end)&&(a[end]>=pivotValue)){ --end; } a[start]=a[end]; while ((start<end)&&(a[start]<=pivotValue)) { ++start; } a[end]=a[start]; } a[start]=pivotValue; return start; } private static void swap(int[] nums,int i ,int j){ int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; } } ``` #### 实战演练与总结反思 通过大量高质量的真题练习提高解题速度和准确性。每次做完一套试题后都要认真分析错误原因,并及时调整后续的学习计划。可以考虑建立个人错题集以便更好地回顾易错点并加深印象。 #### 寻求外部资源支持 利用网络平台查找更多优质教程视频或者加入在线社区与其他参赛者交流心得经验。如果遇到难以解决的问题也可以向有经验的同学请教或是咨询指导教师的意见建议[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值