0
点赞
收藏
分享

微信扫一扫

第八届蓝桥杯省赛真题

dsysama 2022-04-02 阅读 53

目录

1.购物单

2.纸牌三角形

 3.承压计算

4.魔方状态

5.取位数

6.最大公共子串

7.日期问题

输入描述

输出描述

8.包子凑数

9.分巧克力

10.k倍区间


1.购物单

小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。

这不,大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。

小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。

现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。

取款机只能提供 100100100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。

以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。

本题使用excel,直接求得,不太了解excel的,一定百度看看。

     答案5200

2.纸牌三角形


题目:

A,2,3,4,5,6,7,8,9 共 999 张纸牌排成一个正三角形(AAA 按 111 计算)。要求每个边的和相等。 下图就是一种排法。

这样的排法可能会有很多。

如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?

请你计算并提交该数字。

这道题最直观的方法,就是把所有能够有的可能都一一尝试,然后判断,毕竟只是一个“填空题”还是“第二题”。。。

首先需要解决全排列问题

 public void swap(int [] arr,int i,int j){
	        // 交换函数
	        int temp = arr[i];
	        arr[i] = arr[j];
	        arr[j] = temp;
	    }
	// 对数组arr进行全排列
	    public void perum(int [] arr,int left,int right ){
	        // for循环将数组中所有的元素和第一个元素进行交换。然后进行全排列。
	        // 递归结束条件
	        if(left == right){
	            //  一次递归结束。将整个数组打印出来
	            pringArray( arr,left+1);
	        }
	        for(int i =left ;i <= right;i++){
	            swap(arr,i,left);
	            // 把剩下的元素都做全排列。
	            perum(arr,left+1,right);
	            // 然后再交换回去,数组还原,保证下一次不会有重复交换。
	            swap(arr,i,left);
	        }
	    }
	    public void pringArray(int [] arr,int n){
	        // 打印数组
	        for (int i = 0; i < n; i++) {
	            System.out.print(arr[i]);
	        }
	        System.out.println();
	    }
	    @Test
	    public void test1() {
	    	int arr[] ={1,2,3};
	        Main practice_perum = new Main();
	        practice_perum.perum(arr,0,arr.length-1);
	    }

 全排列的测试结果是这样

然后再根据全排列的结果去判断是否符合题意

	        int arr[] ={1,2,3,4,5,6,7,8,9};
	        Main practice_perum = new Main();
	        practice_perum.perum(arr,0,arr.length-1);
	        System.out.println(count/3/2);//以为有旋转还有镜像的原因,所以除于六的出的是正确答案

得到正确答案144

 3.承压计算

这道题也是直接做,就是要处理边界问题,所以提前把边界填上0的话,会好处理特别特别多。

public static void main(String[] args) {
	        int[] a= {7,
	        		5,8,
	        		7,8,8,
	        		9,2,7,2,
	        		8,1,4,9,1,
	        		8,1,8,8,4,1,
	        		7,9,6,1,4,5,4,
	        		5,6,5,5,6,9,5,6,
	        		5,5,4,7,9,3,5,5,1,
	        		7,5,7,9,7,4,7,3,3,1,
	        		4,6,4,5,5,8,8,3,2,4,3,
	        		1,1,3,3,1,6,6,5,5,4,4,2,
	        		9,9,9,2,1,9,1,9,2,9,5,7,9,
	        		4,3,3,7,7,9,3,6,1,3,8,8,3,7,
	        		3,6,8,1,5,3,9,5,8,3,8,1,8,3,3,
	        		8,3,2,3,3,5,5,8,5,4,2,8,6,7,6,9,
	        		8,1,8,1,8,4,6,2,2,1,7,9,4,2,3,3,4,
	        		2,8,4,2,2,9,9,2,8,3,4,9,6,3,9,4,6,9,
	        		7,9,7,4,9,7,6,6,2,8,9,4,1,8,1,7,2,1,6,
	        		9,2,8,6,4,2,7,9,5,4,1,2,5,1,7,3,9,8,3,3,
	        		5,2,1,6,7,9,3,2,8,9,5,5,6,6,6,2,1,8,7,9,9,
	        		6,7,1,8,8,7,5,3,6,5,4,7,3,4,6,7,8,1,3,2,7,4,
	        		2,2,6,3,5,3,4,9,2,4,5,7,6,6,3,2,7,2,4,8,5,5,4,
	        		7,4,4,5,8,3,3,8,1,8,6,3,2,1,6,2,6,4,6,3,8,2,9,6,
	        		1,2,4,1,3,3,5,3,4,9,6,3,8,6,5,9,1,5,3,2,6,8,8,5,3,
	        		2,2,7,9,3,3,2,8,6,9,8,4,4,9,5,8,2,6,3,4,8,4,9,3,8,8,
	        		7,7,7,9,7,5,2,7,9,2,5,1,9,2,6,5,3,9,3,5,7,3,5,4,2,8,9,
	        		7,7,6,6,8,7,5,5,8,2,4,7,7,4,7,2,6,9,2,1,8,2,9,8,5,7,3,6,
	        		5,9,4,5,5,7,5,5,6,3,5,3,9,5,8,9,5,4,1,2,6,1,4,3,5,3,2,4,1};
	        double[][] nums=new double[30][];
	        int n=0;
	        //将数据处理到二维数组中
	        for(int i=0;i<29;i++) {
	        	System.out.print("这是"+i+" ");
	        	double[] temp=new double[i+1];
	        	for(int j=0;j<=i;j++) {
	        		temp[j]=a[n];
	        		n++;
	        		System.out.print(temp[j]+" ");
	        	}
	        	nums[i]=temp;
	        	
	        	System.out.println();
	        	
	        }
	        //需要求的那一行在第30行 有30个数 即是nums[29]
	        nums[29]=new double[30];
	       
	        //先计算前面重量的累计
	        for(int i=1;i<29;i++){
	          for(int j=0;j<=i;j++){//每一个块此时的重量应该是自己加上上面压下来的部分
	            if(j==0) {//因为一开始没有设置边界 所以这个时候要考虑边界问题
	            	nums[i][j]+=nums[i-1][j]/2.0;
	            }else if(j==i) {
	            	nums[i][j]+=nums[i-1][j-1]/2.0;
	            }else {
	            	nums[i][j]+=nums[i-1][j-1]/2.0+nums[i-1][j]/2.0;
	            }
	            
	          }
	        }
	        double max=0,min=1e6+5;
	        for(int i=0;i<30;i++){//计算第30层每个电子秤的承重
	            if(i==0) {
	            	nums[29][i]=nums[28][i]/2;
	            }else if(i==29) {
	            	nums[29][i]=nums[28][i-1]/2;
	            }else {
	            	nums[29][i]=nums[28][i-1]/2+nums[28][i]/2;
	            }
	            System.out.println(nums[29][i]);
	            if(nums[29][i]>max)
	                max=nums[29][i];
	            if(nums[29][i]<min)
	                min=nums[29][i];
	        }
	        //因为我们不知道电子秤的计数规则,所以我们必须要换算一下,因为我们测的本来就和题目中的最小不一样
	        //min*x=2086458231
	        //max*x=所求值
	        System.out.println((2086458231/min)*max);
	        
	        
	    }

4.魔方状态

5.取位数

求1个整数的第k位数字有很多种方法。 以下的方法就是一种。

请仔细分析源码,填写划线部分缺少的内容。

没啥难度


public class Main {
	  
	 static int len(int x){//得到的是位数
	        if(x<10) return 1;
	        return len(x/10)+1;
	    }
	    
	    // 取x的第k位数字
	    static int f(int x, int k){
	        if(len(x)-k==0) return x%10;//等于说一直缩小到位数到想要的 然后再对个位取余
	        return ______;  //填空  f(x/10,k)
	    }
	    
	    public static void main(String[] args)
	    {
	        int x = 23513;
	        //System.out.println(len(x));
	        System.out.println(f(x,3));
	        System.out.println(135%10);
	        System.out.println(f(893275,2));
	    }


}

6.最大公共子串

	 static int f(String s1, String s2)
	    {
	        char[] c1 = s1.toCharArray();
	        char[] c2 = s2.toCharArray();
	        
	        int[][] a = new int[c1.length+1][c2.length+1];
	        
	        int max = 0;
	        for(int i=1; i<a.length; i++){
	            for(int j=1; j<a[i].length; j++){
	                if(c1[i-1]==c2[j-1]) {
	                    a[i][j] =_______;//代码补齐 a[i-1][j-1]+1 
	                    if(a[i][j] > max) max = a[i][j];
	                }
	            }
	        }
	        
	        return max;
	    }
	    
	    public static void main(String[] args){
	        int n = f("abcdkkk", "baabcdadabc");
	        System.out.println(n);
	        System.out.println(f("aaakkkabababa", "baabababcdadabc"));
	        System.out.println(f("abccbaacbcca", "ccccbbbbbaaaa"));
	        System.out.println(f("abcd", "xyz"));
	        System.out.println(f("ab", "ab"));
	        
	    }

7.日期问题

这个虽然不是一道难题,但是好花时间,而且有很多可以调整优化的地方。就是暴力的方式来做,没有什么算法。但是我实在不想做了,可以从判断日期是否合法的角度调优

public class Main {
	  
	 public static void main(String[] args) {
	        Scanner scan = new Scanner(System.in);
	        //在此输入您的代码...
	        String str=scan.nextLine();//输入
	        
	       
	        int[] data=new int[6];//创建一个存储数字的数组
	        
	        for(int i=0,j=0;i<str.length();i++) {//将字符串中的数字放到数组
	        	if(str.charAt(i)=='/') {
	        		//什么也不干
	        	}else {
	        		data[j]=str.charAt(i)-48;
	        		j++;
	        	}
	        	
	        }
	        int t1=data[0]*10+data[1];
	        int t2=data[2]*10+data[3];
	        int t3=data[4]*10+data[5];
	        
	        Riqi time1=new Riqi(1900+t1,t2,t3);
	        Riqi time2=new Riqi(2000+t1,t2,t3);
	        Riqi time3=new Riqi(1900+t3,t1,t2);
	        Riqi time4=new Riqi(2000+t3,t1,t2);
	        Riqi time5=new Riqi(1900+t3,t2,t1);
	        Riqi time6=new Riqi(2000+t3,t2,t1);
	        
	        Riqi[] times= {time1,time2,time3,time4,time5,time6}; 
	        //去重
	        List<String> list=new ArrayList<>();
	        for(Riqi timeN:times) {
	        	if(panduan(timeN)) {
	        		
	        		if(!list.contains(timeN.toString())) {
	        			timeN.PrintF();
	        			System.out.println();
	        		}
	        		list.add(timeN.toString());
	        	}
	        }
	        scan.close();
	    }
	 
	 //判断日期是否合法的方法
	 public static boolean panduan(Riqi time) {
		 int[] mouthOrder= {0,31,28,31,30,31,30,31,31,30,31,30,31};
		 if(time.year>2059||time.year<1960||time.mouth>12||time.day>31) {//初步筛选
			
			 return false;
		 }
		 
		 if(time.year%4==0&&time.year%100!=0) {//闰年的话 需要遵守这个规则
			 if(time.mouth==2) {//闰年的二月
				 if(time.day>29) {
					 
					 return false;
				 }
			 }else if(time.day>mouthOrder[time.mouth]) {//闰年的其他月份
				 return false;
			 }
			
		 }else if(time.day>mouthOrder[time.mouth]) { //不闰年的话 这个规则
			
			 return false;
		 }
		 return true;
		 
	 }
}
class Riqi{
	int year;
	int mouth;
	int day;
	
	public Riqi() {
		super();
	}

	public Riqi(int year, int mouth, int day) {
		super();
		this.year = year;
		this.mouth = mouth;
		this.day = day;
	}
	//可以调整输出的格式  xxxx/xx/xx
	public void PrintF() {
		System.out.printf("%d-%02d-%02d",year,mouth,day);
	}
	//没有使用这个
	@Override
	public String toString() {
		
	
		return year + "-" + mouth + "-" + day;
	}
	
	
}

8.包子凑数

题目的意思就是题目的意思,。。。。,

总的来说,我们可以分成两个情况,笼屉大小的最大公约数,是否为1.比如说,如果有两个笼屉,分别为2,4,那么他们的最大公约数为2,而且他们是拼不出任何一个奇数的,其他公约数不为1的情况都同理,都有无限个凑不出的情况。只有公约数为1的才有有限个。

在求是否可以凑出的时候,我们可以看,剪去一个笼屉是否能够凑出,如果前一个可以,那么这个也可以,具体的过程如果自己画一遍的话,就容易理解了


 public static void main(String[] args) {
	 Scanner scan = new Scanner(System.in);
     //在此输入您的代码...

	 int n=scan.nextInt();//N
	 int arr[] = new int[102];//每个笼屉能够装的数量
	 arr[1]=scan.nextInt();
	 int temp=arr[1];
	 //获得arr 并且得到最大公约数
	 for(int i=2;i<=n;i++) {
		 arr[i]=scan.nextInt();
		 temp=gcd(temp, arr[i]);
	 }
	 //结果数组
	 int[] dp = new int[100004];
	 dp[0]=1;
	 for(int i=1;i<=n;i++) {
		 for(int j=arr[i];j<100004;j++) {//画一画就容易理解
			 if(dp[j-arr[i]]==1)
				 dp[j]=1;
		 }
	 }
	 int ans=0;
	 for(int i=1;i<100004;i++) {
		 if(dp[i]!=1)
			 ans++;
	 }
	 if(temp>1) {
		 System.out.println("INF");
	 }else {
		 System.out.println(ans);
	 }
	 
     scan.close();
 
 }
 //求最大公约数
 private static int gcd(int a, int b) {
     // TODO Auto-generated method stub
     return  b==0?a:gcd(b,a%b);
 }

9.分巧克力

10.k倍区间

举报

相关推荐

0 条评论