第八届 蓝桥杯 省赛 java B

第一题
标题: 购物单
小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。
不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。
小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。
现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。
取款机只能提供100元面额的纸币。小明想尽可能少取些现金,够用就行了。
你的任务是计算出,小明最少需要取多少现金。
以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。
--------------------
****     180.90       88折
****      10.25       65折
****      56.14        9折
****     104.65        9折
****     100.30       88折
****     297.15       半价
****      26.75       65折
****     130.62       半价
****     240.28       58折
****     270.62        8折
****     115.87       88折
****     247.34       95折
****      73.21        9折
****     101.00       半价
****      79.54       半价
****     278.44        7折
****     199.26       半价
****      12.97        9折
****     166.30       78折
****     125.50       58折
****      84.98        9折
****     113.35       68折
****     166.57       半价
****      42.56        9折
****      81.90       95折
****     131.78        8折
****     255.89       78折
****     109.17        9折
****     146.69       68折
****     139.33       65折
****     141.16       78折
****     154.74        8折
****      59.42        8折
****      85.44       68折
****     293.70       88折
****     261.79       65折
****      11.30       88折
****     268.27       58折
****     128.29       88折
****     251.03        8折
****     208.39       75折
****     128.88       75折
****      62.06        9折
****     225.87       75折
****      12.89       75折
****      34.28       75折
****      62.16       58折
****     129.12       半价
****     218.37       半价
****     289.69       8折
--------------------


需要说明的是,88折指的是按标价的88%计算,而8折是按80%计算,余者类推。
特别地,半价是按50%计算。


请提交小明要从取款机上提取的金额,单位是元。

答案是一个整数,类似4300的样子,结尾必然是00,不要填写任何多余的内容。


 * 方法:

 * 1 复制到 txt 替换字符

import java.util.Scanner;
import java.util.Scanner;public class _1 {

	public static void main(String[] args) {

		double sum= (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);
		
		System.out.println(sum);
	}

}


2 标题:纸牌三角形


        A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
        下图就是一种排法(如有对齐问题,参看p1.png)。

              A
             9 6
            4   8
           3 7 5 2

        这样的排法可能会有很多。
        如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
        请你计算并提交该数字。

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

public class _2 {
	 static int[] first = new int[9];  
	    static int[] s = new int[9];  
	    static int sum = 0;  
	    public static void main(String[] args) {  
	        sousuo(0);  
	        System.out.println(sum/6);  
	    }  
	    public static void sousuo(int code){  
	        if(code==9){  
	            if(s[0]+s[1]+s[3]+s[5]==s[0]+s[2]+s[4]+s[8]&&s[0]+s[1]+s[3]+s[5]==s[5]+s[6]+s[7]+s[8])  
	                sum++;  
	        	for(int k:s)
	        	System.out.print(" "+k);
	        	System.out.println();
	            return;  
	        }  
	        for (int i = 0; i < 9; i++) {  
	            if(first [i]==0){  
	                first [i] = 1;  
	                s[code] = i+1;  
	                sousuo(code+1);  
	                first [i] = 0;  
	            }  
	        }  
	    } 
}

/*
 * 1.发现规律  /6
 * 2.全排列递归
 *  
 1 2 3
 1 3 2
 2 1 3
 2 3 1
 3 2 1
 3 1 2
 
 
 1 2 3
 1 3 2
 3 1 2
 3 2 1
 1 2 3
 1 3 2
 
 */
public class _21 {
	static int a=0;
	public static void main(String[] args) {
		int []arr = {1,2,3,4,5,6,7,8,9};
		f(arr,0,9);
		System.out.println("  "+a/6);
	}

	private static void f(int[] arr, int i, int j) {
		// TODO 自动生成的方法存根
		if(i==j){
			if(arr[0]+arr[1]+arr[2]+arr[3]==arr[3]+arr[4]+arr[5]+arr[6]&&arr[3]+arr[4]+arr[5]+arr[6]==arr[6]+arr[7]+arr[8]+arr[1])
				a++;
		}
		for(int k =i;k

第三题:承压计算
X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。


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



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


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


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


要点:只要把第i行的第j个平均分给第i+1行的第j个和第i+1行的第j+1个


import java.util.Arrays;
public class _3 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		double [][]arr =  {
				{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},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
		
				for (int i=0; i

5 标题:取数位 


标题:取数位

求1个整数的第k位数字有很多种方法。
以下的方法就是一种。
对于题目中的测试数据,应该打印5。

请仔细分析源码,并补充划线部分所缺少的代码。

注意:只提交缺失的代码,不要填写任何已有内容或说明性的文字。。 

今年的代码填空异常简单,10min做完全部。没什么好说的。


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));  
    }  
}
6 标题:最大公共子串

最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。
比如:"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 max) max = a[i][j];  
                }  
            }  
        }  
  
        return max;  
    }  
  
    public static void main(String[] args){  
        int n = f("abcdkkk", "baabcdadabc");  
        System.out.println(n);  
    }  
} 
7,标题:日期问题


小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。  


比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。  


给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?


输入
----
一个日期,格式是"AA/BB/CC"。  (0 <= A, B, C <= 9)  


输出
----
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。  


样例输入
----
02/03/04  


样例输出
----
2002-03-04  
2004-02-03  

2004-03-02


import java.util.Scanner;

import org.junit.Test;


public class _7 {
	
	static int monday[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Scanner reader  = new Scanner(System.in);
		String s = reader.nextLine();
		String [] ss = s.split("/");
		int a,b,c;
		a = Integer.valueOf(ss[0]);
		b = Integer.valueOf(ss[1]);
		c = Integer.valueOf(ss[2]);
		
		f1(a,b,c);
		
		f1(c,b,a);
		f1(b,c,a);
		
	}
	//年月日
	private static void f1(int a, int b, int c) {
		boolean flag=true;
		String year = "";
		String mon = "";
		String day = "";
		
		year = foryear(a, year);
		
		
		if(1<=b&&b<=12)
		{
			mon = forMon(b, mon);

		}
		else
			flag=false;
		
		
		if(flag){
			if(b==2&&judgeMon(year))
			{
				if(c>29)
					flag=false;
			}
			 if(c>monday[b])
			{	
					flag=false;
			}
			 if(c==0)
			 {
				 flag=false;
			 }
			if(flag){
				
				day = forday(c, day);
			}
			
		}
		
		if(flag)
			System.out.println(year+"-"+mon+"-"+day);
			
	}
	private static String forday(int c, String day) {
		if(c>10)
			day+=c;
		else
			day+="0"+c;
		return day;
	}
	private static String forMon(int b, String mon) {
		if(b>=10)
			mon+=b;
		else
			mon+="0"+b;
		return mon;
	}
	
	
	
	private static String foryear(int a, String year) {
		if(judgeYear(a))
			year+="19"+a;
		else
		{
			if(a>10)
				year+="20"+a;
			else
				year+="200"+a;
		}
		return year;
	}
	
	
	@Test
	private static boolean judgeMon(String year) {
		int y = Integer.valueOf(year);
		if(y%4==0||y%100==0&&y%400==0)
			return true;
		return false;
	}
	
	private static boolean judgeYear(int a) {
		
		if(a>59)
			return true;
		else
			return false;
	}

		
	

}
8 标题:包子凑数

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,
其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。

每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,
使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。
当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。

当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。
而顾客想买7个包子时,大叔就凑不出来了。

小明想知道一共有多少种数目是包子大叔凑不出来的。

输入
----
第一行包含一个整数N。(1 <= N <= 100)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100)  

输出
----
一个整数代表答案。如果凑不出的数目有无限多个,输出INF。

例如,
输入:
2  
4  
5   

程序应该输出:
6  

再例如,
输入:
2  
4  
6    

程序应该输出:
INF
样例解释:
对于样例1,凑不出的数目包括:1, 2, 3, 6, 7, 11。  

对于样例2,所有奇数都凑不出来,所以有无限多个。

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;
public class _8 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Scanner reader = new Scanner(System.in);
		int num = reader.nextInt();
		int []arr = new int[101];
		Set setnum = new HashSet();
		
		for(int i=0;i set1 = new LinkedHashSet();
		Set set2 = new LinkedHashSet();
		int []v = new int[100000];
		int a = 0,b=0;
		Arrays.sort(arr);
		boolean ji=true,ou=true;
		int count=0;
		for(int i:arr){
			v[i]=i;
			v[i*i]=i*i;
	
			if(ji)
			{
				if (i%2==1)
					b=i;
			}
			if(ou)
			{
				if(i%2==0)
					a=i;
			}

		}
		dnf(arr,0,v);
		
		
		for(int k=0;k<10000;k++){

			v[v[k]+a] = v[k]+a;
			v[v[k]+b] = v[k]+b;
			
		}
		for(int l =1; l<10000; l++){
			if(v[l]==0)
				count++;
		}
		
		System.out.println(count);
		return 0;
	
	}

	private static void dnf(int[] arr, int i, int[] v) {
		if(i==arr.length-1)
			return;
		
		for(int j=i+1; j
9 标题: 分巧克力


    儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
    小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。


    为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:


    1. 形状是正方形,边长是整数  
    2. 大小相同  


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


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


输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)  
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000) 
输入保证每位小朋友至少能获得一块1x1的巧克力。   


输出
输出切出的正方形巧克力最大可能的边长。


样例输入:
2 10  
6 5  
5 6  


样例输出:

2

import java.util.Scanner;
public class _9 {

	public static void main(String[] args) {
		int n,m;
		int[][]arr = null;
		Scanner reader = new Scanner(System.in);
		n=reader.nextInt();
		m=reader.nextInt();
		arr = new int[n][2];
		for(int i=0;i
10,标题: k倍区间


给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列
Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。  


你能求出数列中总共有多少个K倍区间吗?  


输入
-----
第一行包含两个整数N和K。(1 <= N, K <= 100000)  
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)  


输出
-----
输出一个整数,代表K倍区间的数目。  


例如,
输入:
5 2
1  
2  
3  
4  
5  


程序应该输出:

6


import java.util.Scanner;
public class _10 {

	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);
		int a = reader.nextInt();
		int b = reader.nextInt();
		int []arr = new int[a];
		for(int i=0; i

你可能感兴趣的:(蓝桥杯)