2017蓝桥杯第八届真题 java_B组题目+题解

在这里插入图片描述

1 、 购物单:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目分析+代码
评测标准答案: 5200
方法1: 在excel中计算,复制粘贴后对数据进行以空格为标志分列,删除汉字,用公式计算。
方法2: 用计算机自带的计算器计算。
方法3: 将购物单复制到代码中,把**** 替换成`+`号,去掉汉字`折`,改为两位数 
         即9折改成90,在数字间加上 `*`,计算结果除以100即可,此方法不至于输入错误。
public class Main001{
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         double ans = 180.90    *    88
		+     10.25    *    65
 		+     56.14    *    90
		+     104.65   *    90
		+     100.30   *    88
	        +     297.15   *    50
		+      26.75   *    65
   		+     130.62   *    50
    		+     240.28   *    58
    		+     270.62   *    80
    		+     115.87   *    88
    		+     247.34   *    95
    		+      73.21   *    90
    		+     101.00   *    50
    		+      79.54   *    50
    		+     278.44   *    70
    		+     199.26   *    50
    		+      12.97   *    90
    		+     166.30   *    78
    		+     125.50   *    58
    		+      84.98   *    90
    		+     113.35   *    68
    		+     166.57   *    50
    		+      42.56   *    90
    		+      81.90   *    95
    		+     131.78   *    80
    		+     255.89   *    78
    		+     109.17   *    90
    		+     146.69   *    68
    		+     139.33   *    65
    		+     141.16   *    78
    		+     154.74   *    80
    		+      59.42   *    80
    		+      85.44   *    68
    		+     293.70   *    88
    		+     261.79   *    65
    		+      11.30   *    88
    		+     268.27   *    58
    		+     128.29   *    88
    		+     251.03   *    80
    		+     208.39   *    75
    		+     128.88   *    75
    		+      62.06   *    90
    		+     225.87   *    75
    		+      12.89   *    75
   		+      34.28   *    75
    		+      62.16   *    58
    		+     129.12   *    50
    		+     218.37   *    50
    		+     289.69   *    80;
 	  System.out.println(ans/100);
     }
}

在这里插入图片描述

2 、纸牌三角形:

在这里插入图片描述

题目分析+代码
评测标准答案: 144
1~9的数字进行全排列,然后 
if(a[0]+a[1]+a[3]+a[5] = a[0]+a[2]+a[4]+a[8] 
    && a[0]+a[2]+a[4]+a[8]= a[5]+a[6]+a[7]+a[8]) 
       count++;
 因为旋转、镜像后相同的视为同一种,answer = count/6;
public class Main002{
    static int [] a = new int[] {1,2,3,4,5,6,7,8,9};
    static int count = 0;
    public static void f(int k) {
  	if(k==9) {
   		// 判断三边之和是否相等,若相等 count++;
	     int x1 = a[0]+a[1]+a[3]+a[5];
	     int x2 = a[0]+a[2]+a[4]+a[8];
	     int x3 = a[5]+a[6]+a[7]+a[8];
	     if(x1==x2 && x2 ==x3)   count++;
         }
 	 /*   对 1~9 进行全排列,
 	  *   把第 k 位以后的每一位交换到第一位
 	      递归+回溯                    */
 	 for(int i=k;i<9;i++) {
	      int t = a[k];
	      a[k] = a[i];
	      a[i] = t;
	      f(k+1);
	      t= a[k];
	      a[k] = a[i];
	      a[i] = t;
 	 }
    }
    public static void main(String[] args) {
 	 // TODO Auto-generated method stub
 	 f(0);
	 System.out.println(count/6);
    }
}

在这里插入图片描述

3 、承压计算:

在这里插入图片描述
在这里插入图片描述

题目分析+代码
评测标准答案:72665192664
方法一:
	1.注意物品的单位和电子称的单位不同
	2.数字 29*29列,开3030列数组,以便保存最终数据
	2.构造二维数组 将数据存入二维数组。双层循环,内循环的循环次数依次增大,
	   读入数据(直接粘贴29行即可),读入多个空格作为分隔符。
	3.更新每一行数组,a[i+1][j] +=a[i][j]/2 ; a[i+1][j+1] += a[i][j]/2;
	   每一个数据均分给 正下方和右下方的元素。
	4.数组最后一行,为称的示数。进行排序。  
	5.题目给出的最小示数/求得的最小示数 = 单位的倍数
	   求得的最大示数 * 单位的倍数 = answer;
	6. 涉及到除法,可能会出现小数,so用double数据类型
方法二:  先扩大230次方倍,再同理计算。
import java.util.Arrays;
import java.util.Scanner;
public class Main003{
    static double[][] a  = new double[30][30];
 	public static void main(String[] args) {
  	Scanner in = new Scanner(System.in);
  	for(int i=0;i<29;i++) 
	    for(int j=0;j<=i;j++) 
	        a[i][j]=in.nextDouble();
	for(int i=0;i<29;i++) 
	    for(int j=0;j<=i;j++){
	        a[i+1][j] +=a[i][j]/2 ;
      		a[i+1][j+1] += a[i][j]/2;
      	    }
 	Arrays.sort(a[29]);
  	double answer = a[29][29]*(2086458231/a[29][0]);
  	System.out.println((long)answer);
    }
}

在这里插入图片描述

4、魔方状态

在这里插入图片描述
在这里插入图片描述

评测标准答案:229878
" emmmmmm 这道题我放弃了!不会写。"
5、取数位(代码填空)

在这里插入图片描述

评测标准答案:f(x/10, k)
import java.util.*;
public class Main005{
     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));
     }
}
6、最大公共子串(代码填空)

在这里插入图片描述

评测标准答案:a[i-1][j-1]+1
public class Main{
    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);
     }
}
7 、 日期问题

在这里插入图片描述

题目分析+代码
1.获取 year、moth、day三个数据
2.写一个读入数据,并判断日期是否合理的方法
3.注意判断是否为闰年
4.调用方法时,传入三种不同顺序的参数
5.生成字符串时,注意小于10的月份和天数前加上0
6.用TreeSet存储字符串,以达到去重和按字典序排序的效果

在这里插入图片描述

import java.Util.*;
public class Main{
    static Set<String> set = new TreeSet<String>(); 
    public static boolean isLeapYear(int year){
        return year%400==0 || ( year%4==0 && year%100 !=0 );
    }
    public static void check(int a,int b , int c){
        if(a>=60 && a<=99)  a += 1900;
        else if(a>=0  && a<=59)  a += 2000;
  	else return;
  	if(b>12||b<=0) return;
  	if(c>31||b<=0) return;
  
  	switch (b) {
	  	case 4:
	  	case 6:
	  	case 9:
	  	case 11:
	   	if(c>30) return ;
	   	break;
	  	case 2:
	   	if(isLeapYear(a)) {
	    	    if(c>29) return;
	   	}else {
	    	    if(c>28) return;
	        }
         }
	 set.add(a+"-"+(b<10?"0"+b:b)+"-"+(c<10?"0"+c:c));
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
  	Scanner in = new Scanner(System.in);
  	String s = in.next();
  	int a = (s.charAt(0)-'0')*10+s.charAt(1)-'0';
  	int b = (s.charAt(3)-'0')*10+s.charAt(4)-'0';
  	int c = (s.charAt(6)-'0')*10+s.charAt(7)-'0';
  	check(a, b, c);
  	check(c, a, b);
  	check(c, b, a); 
  	for(String str:set) {
   	    System.out.println(str);
 	}
   }
}
8 、 包子凑数

在这里插入图片描述
在这里插入图片描述

题目分析+代码
1.由扩展欧几里算法
   ax + by + cz = m ;  当m不是gcd(a,b,c)的倍数时,无解。
   <"对本题而言:若输入的数不互质,则凑不出的数有无数个">
2.对任何整数 a,b 和他们的最大公约数d,关于未知数 x和 y的线性丢番图方程(称为裴蜀等式): 
    ax + by = m 有整数解时,当且仅当m是d的倍数。
3. 裴蜀等式 有解时必然有无穷多个整数解,每组解x,y都称为裴蜀数
4. 当最大公约数为1时,即互质
   如果 某个数能凑出,那么它加上任意一个输入的包子数,都能凑出
   so,从零到10000扫描n次 ,逐个检查是否能凑出  

在这里插入图片描述

import java.util.Scanner;
public class Main{
      //  计算两个数的最大公约数
    static int gcd1 (int a,int b){
        return b==0?a:gcd1(b,a%b);
    }
      //  计算多个数的最大公约数
    static int gcd2(int [] a){
        int n = a.length;
        int L = a[0];
        for(int i=1;i<n;i++)
            L = gcd1(L,a[i]);
        return L;
     } 
     public static void main(String[] args) {
  	 // TODO Auto-generated method stub
  	 Scanner in = new Scanner(System.in);
 	 int n = in.nextInt();
 	 int [] a = new int[n];
 	 boolean []b = new boolean [10000];
 	 b[0] = true;
 	 for(int i=0;i<n;i++) {
  	     a[i]=in.nextInt();
 	 }
 	 int gcd = gcd2(a);
 	 /* 如果最大公约数不为1,一定有无数个数凑不出来
 	  *   例如 , 多个数的最大公约数为2 ,则所以的 奇数都凑不出
  	 */
 	 if(gcd!=1) {
 	 System.out.println("INF");
  	 System.exit(0);  // 输出"INF"终止程序
 	 }else {  
 	  	/*  当最大公约数为1时,即互质
   	  	*   如果 某个数能凑出,那么它加上任意一个输入的包子数,都能凑出
                    so,从零到10000扫描n次 ,逐个检查是否能凑出         */
   	     for(int i = 0;i<n;i++) {
   	         for(int j=0;j+a[i]<10000;j++) {
     	             if(b[j]) b[j+a[i]] = true;
    	         }
             }
         }
         int count = 0;  //计数,记录凑不出的数
  	 for(int i=0;i<10000;i++) {
   	     if(b[i]==false) count++;
  	 }
  	 System.out.println(count);
    }
}
9 、 分巧克力

在这里插入图片描述

题目分析+代码
1.如果单独的使用逐个循环暴力,必超时
2.使用二分法降低复杂度 直到 l=r=mid ,得出最终结果
import java.util.Scanner;
public class Main009_分巧克力 {
    public static void main(String[] args) {
	   Scanner in = new Scanner(System.in);
	   int n = in.nextInt();
	   int k = in.nextInt();
	   int []h = new int[n];
	   int []w = new int[n];
	   for(int i=0;i<n;i++) {
	        h[i]=in.nextInt();
	        w[i]=in.nextInt();
	 }
	 int l = 1,r=100001,ans=0;
   	 while(l<=r) {
	        int count=0;
	        int mid=(l+r)/2;
	        for(int i=0;i<n;i++) {
             		count += (h[i]/mid)*(w[i]/mid);
        	}
        	if(count>=k) {
             		l=mid+1;
             		ans = mid;
        	}else {
             		r=mid-1;
        	}
        }
        System.out.println(ans);
    }
}
10 、 K倍区间

在这里插入图片描述

题目分析+代码
1.对于本题评测标准共7个测试用例,前两个数据个数为100,余数9个,
   后5个为100000,余数成倍增加   
   虽然本题的时间限制是2秒,但也要进行优化。

在这里插入图片描述

方法:前缀和+取模+组合数学
  1.  a数组存储数据,dp数组为前缀和取模后的数组
  2.  前缀和数组,即dp的某项元素 为a数组相应位置及之前数组元素之和。
  3.  dp数组,为取模后的数组。例:输入 n=5,k=2;  a={1,2,3,4,5},前缀和={1361015};
      引入前缀和的原因: 前缀和的任意两项相减都为 数组a的一个连续区间和,可简便计算。
  4.  取模后 dp={1,1,0,0,1} 任意两项相减为0,那么该区间必能整除k; 所以任意余数相等的元素必能凉凉组合。
  5. 不要忽略了,单独的一个元素,也可作为子区间。所以最后应加上,余数为0的元素个数。
  6. ans+=count[dp[i]]++; 此行代表每增加一个新的余数,
     都能和之前已有的相同余数形成区间,所以ans加上之前已有的该余数的个数(不包括本次)
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
  	Scanner in = new Scanner(System.in);
  	int n = in.nextInt();
  	int k = in.nextInt();
  	int[]a = new int[n];
  	int[]dp = new int[n];
  	int[]count = new int[k];
  	int last = 0;
  	long ans = 0;
  	for(int i=0;i<n;i++) {
   	    a[i]=in.nextInt();
   	    dp[i] = (last+a[i])%k;
   	    last = dp[i];
   	    ans+=count[dp[i]]++;
  	}
	//  for(int i=0;i<k;i++) {
	//   ans += count[i]*(count[i]-1)/2;
	//  }
	 System.out.println(ans+count[0]);
   }
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值