兔宝宝刷题:2017蓝桥杯省赛真题

1.购物单(5/5分)

答案:5200

我在其他博主那里看到有一个大佬用excel方法计算很快,链接在下面啦

https://www.cnblogs.com/ljmzzyk/p/6918364.html

解题思路:

把题目给的清单复制然后格式化存入二维数组计算,花了二十多分钟T^T

代码如下:

public class a01_shopping {
	public static void main(String[] args) {
		long sum = 0;
		double[][] a = {
				 {180.90,0.88},
				 {10.25,0.65},
				 {56.14,0.9},
				 {104.65,0.9},
				 {100.30,0.88},
				 {297.15,0.5},
				 {26.75,0.65},
				 {130.62,0.5},
				 {240.28,0.58},
				 {270.62,0.8},
				 {115.87,0.88},
				 {247.34,0.95},
				 {73.21,0.9},
				 {101.00,0.5},
				 {79.54,0.5},
				 {278.44,0.7},
				 {199.26,0.5},
				 {12.97,0.9},
				 {166.30,0.78},
				 {125.50,0.58},
				 {84.98,0.9},
				 {113.35,0.68},
				 {166.57,0.5},
		    	 {42.56,0.9},
				 {81.90,0.95},
				 {131.78,0.8},
				 {255.89,0.78},
				 {109.17,0.9},
				 {146.69,0.68},
				 {139.33,0.65},
				 {141.16,0.78},
				 {154.74,0.8},
				 {59.42,0.8},
				 {85.44,0.68},
				 {293.70,0.88},
				 {261.79,0.65},
				 {11.30,0.88},
				 {268.27,0.58},
				 {128.29,0.88},
				 {251.03,0.8},
				 {208.39,0.75},
				 {128.88,0.75},
				 {62.06,0.9},
				 {225.87,0.75},
				 {12.89,0.75},
				 {34.28,0.75},
				 {62.16,0.58},
				 {129.12,0.5},
				 {218.37,0.5},
				 {289.69,0.8}
		};
		for (int i = 0; i < a.length; i++) {
			sum += a[i][0] * a[i][1];
		}
		System.out.println(sum + 90);
	}
}

2.纸牌三角形(11/11分)

解题思路:

得到从1-9一共9个数字的全排列,然后判断这个数组的0,2,4,8索引的数字的和与0,1,3,5索引的数字的和与5,6,7,8索引上的数字的和是否相等,相等则计数器++,因为镜像和旋转不算所以统计完成后得到的结果要除以6,本题的难点在于怎么得到9个数字的全排列的所有可能性。

但是总共只有九个数字的话可以九层循环判断

代码如下:

public class a02_SanJiao {
	public static void main(String[] args) {
		int cnt = 0;
		for (int a = 1; a < 10; a++) {
			for (int b = 1; b < 10; b++) {
				for (int c = 1; c < 10; c++) {
					for (int d = 1; d < 10; d++) {
						for (int e = 1; e < 10; e++) {
							for (int f = 1; f < 10; f++) {
								for (int g = 1; g < 10; g++) {
									for (int h = 1; h < 10; h++) {
										for (int i = 1; i < 10; i++) {
											if(a != b && a != c && a != d && a != e && 
                                               a != f && a != g && a != h && a != i && 
                                               b != c && b != d && b != e && b != f && 
                                               b != g && b != h && b != i && c != d && 
                                               c != e && c != f && c != g && c != h && 
											   c != i && d != e && d != f && d != g && 
                                               d != h && d != i && e != f && e != g && 
                                               e != h && e != i && f != g && f != h && 
                                               f != i && g != h && g != i && h != i && 
                                               ((a + c + e + i) == (a + b + d + f)) &&
											   ((a + b + d + f) == (f + g + h + i))) {
														cnt++;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		System.out.println(cnt / 6);
	}
}

让我用新学的全排列算法改进一下捏:(泰裤辣!!)

public class a02_SanJiao_02 {
	static int cnt = 0;
	public static void main(String[] args) {
		int[] a = new int[9];
		for (int i = 0; i < a.length; i++) {
			a[i] = i;
		}
		f(a, 0);
		System.out.println(cnt/6);
	}
	public static void f(int[] a,int n) {
		if(n == a.length - 1) {
			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]) {
				cnt++;
			}
		}
		for (int i = n; i < a.length; i++) {
			int t = a[i];a[i] = a[n];a[n] = t;
			f(a,n+1);
			t = a[i];a[i] = a[n];a[n] = t;
		}
	}
}

3.承压计算(0/13分)

X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。

每块金属原料的外形、尺寸完全一致,但重量不同。
金属材料被严格地堆放成金字塔形。

                             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 
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X

其中的数字代表金属块的重量(计量单位较大)。
最下一层的X代表30台极高精度的电子秤。

假设每块原料的重量都十分精确地平均落在下方的两个金属块上,
最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。
电子秤的计量单位很小,所以显示的数字很大。

工作人员发现,其中读数最小的电子秤的示数为:2086458231

请你推算出:读数最大的电子秤的示数为多少?

注意:需要提交的是一个整数,不要填写任何多余的内容。

4.魔方状态(0/17分)

5.取数位(7/7分)

解题思路:

就是用递归解决取数位问题

代码如下:

f(x/10,k-1)

6.最大公共字串

6.最大公共子串(9/9分)

最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。

比如:“abcdkkk” 和 “baabcdadabc”,
可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。

下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。

请分析该解法的思路,并补全划线部分缺失的代码。

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] = __________________;  //填空 
					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);
	}
}

答案:a[i][j]=a[i-1][j-1]+1

解题思路:

一开始没看懂网上也找不到思路,然后在草稿本上自己模拟了一下发现马上清晰了,草稿如图

7.日期问题(9.5/19)

解题思路:

没什么思路,用的最蠢的方法,写完以后发现只能过50%样例,有两方面缺陷:

(1)没有考虑到闰年2月有29天

(2)输出的结果没有排序

代码:

import java.util.Scanner;

public class a06_Date {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		int[] a = {s.charAt(0) - '0',s.charAt(1) - '0'};//年
		int[] b = {s.charAt(3) - '0',s.charAt(4) - '0'};//月
		int[] c = {s.charAt(6) - '0',s.charAt(7) - '0'};//日
		String[] sArr = new String[3];
		//aa/bb/cc ->年/月/日
		if(getSum(a) >= 0 && getSum(a) <= 59) {//21世纪
			if(checkMonth(b)) {
				if(checkDay(getSum(b), c)) {
					sArr[0] = "20" + a[0] + a[1] + "-" + b[0] + b[1] + "-" + c[0] + c[1];
				}
			}
		}
		else {//20世纪
			if(checkMonth(b)) {
				if(checkDay(getSum(b), c)) {
					sArr[0] = "19" + a[0] + a[1] + "-" + b[0] + b[1] + "-" + c[0] + c[1];
				}
			}
		}
		//aa/bb/cc ->月/日/年
		if(getSum(c) >= 0 && getSum(c) <= 59) {//21世纪
			if(checkMonth(a)) {
				if(checkDay(getSum(a), b)) {
					sArr[1] = "20" + c[0] + c[1] + "-" + a[0] + a[1] + "-" + b[0] + b[1];
				}
			}
		}
		else {//20世纪
			if(checkMonth(c)) {
				if(checkDay(getSum(c), b)) {
					sArr[1] = "19" + c[0] + c[1] + "-" + a[0] + a[1] + "-" + b[0] + b[1];
				}
			}
		}
		//aa/bb/cc ->日/月/年
		if(getSum(c) >= 0 && getSum(c) <= 59) {//21世纪
			if(checkMonth(b)) {
				if(checkDay(getSum(b), a)) {
					sArr[2] = "20" + b[0] + b[1] + "-" + a[0] + a[1] + "-" + c[0] + c[1];
				}
			}
		}
		else {//20世纪
			if(checkMonth(c)) {
				if(checkDay(getSum(c), b)) {
					sArr[2] = "19" + b[0] + b[1] + "-" + a[0] + a[1] + "-" + c[0] + c[1];
				}
			}
		}
		for (int i = 0; i < sArr.length; i++) {
			if(sArr[i] != null) {
				System.out.println(sArr[i]);
			}
		}
	}
	public static int getSum(int[] arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum = sum * 10 +arr[i];
		}
		return sum;
	}
	//检查某个日期是否合规
	//年:1960-2059(年份后两位可以从00-99)
	//月:01-12
	//日:01-28,29,30,31
	//1.先判断三个时间作为月份是否满足条件
	public static boolean checkMonth(int[] arr) {
		if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 12) {
			return true;
		}
		else {
			return false;
		}
	}
	//2.再判断三个时间作为天数能不能满足条件
	public static boolean checkDay(int m,int[] arr) {//m表示月份
		if(m == 1 || m == 3 || m == 5 || m== 7 || m== 8 || m== 10 || m== 12) {
			if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 31) {
				return true;
			}
			else {
				return false;
			}
		}
		else if(m == 4 || m== 6 || m== 9 || m== 11) {
			if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 30) {
				return true;
			}
			else {
				return false;
			}
		}
		else {
			if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 29) {
				return true;
			}
			else {
				return false;
			}
		}
	}
}

8.包子凑数(2.3/21分)

解题思路:

没有思路且看不懂答案。但是题目说了有一种情况是输出INF,所以我写的代码是直接输出INF,然后骗了一个测试点的分。

9.分巧克力(17.3/23分)

  

解题思路:最大边长默认从1开始,然后看看这样切割能否满足条件,满足则边长加一,直到切割不出需要的数量,返回这个边长减一。(这是最基础的思路但是只能拿62.5%的分数)

代码如下:

import java.util.Scanner;

public class a08_分巧克力 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//n块巧克力
		int k = sc.nextInt();//需要分成k块巧克力
		int[][] a = new int[n][2];//n行2列的矩阵  第一列表示长,第二列表示宽
		for (int i = 0; i < a.length; i++) {
			a[i][0] = sc.nextInt();//长
			a[i][1] = sc.nextInt();//宽
		}
		int t = 1;//边长
		while(true) {
			int sum = 0;
			for(int i = 0; i < a.length; i++) {
				int len = a[i][0] / t;
				int wid = a[i][1] / t;
				sum += len * wid;
			}
			if(sum <= k) {
				t--;
				break;
			}
			else {
				t++;
			}
		}
		System.out.println(t);
	}
}

解题思路(二分法改进):(75%得分)

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//n块巧克力
		int k = sc.nextInt();//需要分成k块巧克力
		int[][] a = new int[n][2];//n行2列的矩阵  第一列表示长,第二列表示宽
		int max = 0;
		for (int i = 0; i < a.length; i++) {
			a[i][0] = sc.nextInt();//长
			a[i][1] = sc.nextInt();//宽
			if(a[i][0] > max) {
				max = a[i][0];
			}
			if(a[i][1] > max) {
				max = a[i][1];
			}
		}
		int t = max;//边长
		while(true) {
			if(getSum(a, t) < k) {//边长为t时分出的巧克力过少
				t /= 2;
			}
			else if(getSum(a, t) >= k) {
				if(getSum(a, t + 1) < k) {
					break;
				}
				else {
					t++;
				}
			}
		}
		System.out.println(t);
	}
	public static int getSum(int[][] a,int t) {//边长为t的情况下能分出多少块巧克力
		int sum = 0;
		for(int i = 0; i < a.length; i++) {
			int len = a[i][0] / t;
			int wid = a[i][1] / t;
			sum += len * wid;
		}
		return sum;
	}
}

10.K倍区间(9.4/25分)

解题思路:暴力。没有想到优化方法,只能得3/8分数。

代码如下,仅供参考:

import java.util.Scanner;

public class a10_k倍区间 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int k = sc.nextInt();//对比数
		int[] a = new int[n];
		for (int i = 0; i < a.length; i++) {
			a[i] = sc.nextInt();
		}
		int cnt = 0;
		for (int i = 0; i < a.length; i++) {
			int sum = 0;
			for (int j = i; j < a.length; j++) {
				sum += a[j];
				if(sum % k == 0) {
					cnt++;
				}
			}
		}
		System.out.println(cnt);
	}
}

=======================2/29日更新,黑色分数为本次更新内容====================

总分23,惨不忍睹,完全做不下去哇,先往后刷题再回过头学习这些知识点吧。

=======================3/10日更新,红色分数为本次更新内容====================

这次二刷题目发现很难的题目其实也不是完全没有得分点,但是第一次刷的时候看到一些题目直接放弃了思考,这是不可取的!!! 比赛的时候其实很多题目都可以拿到部分分数,切记不能浮躁,保持冷静。

总分:(70.5/150分)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值