第八届蓝桥杯省赛

一、 购物单(使用excel表可能更简单一点)

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

    这不,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,不要填写任何多余的内容。

特别提醒:不许携带计算器入场,也不能打开手机。

excel表中的部分内容:
这里写图片描述

由于题目中要求结尾必须为00.
所以答案为:5200

二、纸牌三角形


标题:纸牌三角形

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

      A
     9 6
    4   8
   3 7 5 2

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

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

请你计算并提交该数字。

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

思路:

求出的所有情况应当将重复的情况去掉。
当为三角形时有三种旋转的重复的,三种镜像重复的。
所以应当除以6.

当为正方形时有四种旋转的重复的,四镜像重复的。
所以应当除以8.

代码如下:

package s_2;
public class Main {
    /**
     * 标题:纸牌三角形
     * 
     * A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
     * 
     * 下图就是一种排法(如有对齐问题,参看p1.png)。
     *       A
     *      9 6
     *     4   8
     *    3 7 5 2
     *    
     *    这样的排法可能会有很多。
     *    
     *    如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
     *    
     *    请你计算并提交该数字。
     *    
     *    注意:需要提交的是一个整数,不要提交任何多余内容。
     *     */
    public static int total=0;
    public static void test(int a[]){
        int i=a[0]+a[1]+a[3]+a[5];
        int j=a[0]+a[2]+a[4]+a[8];
        int k=a[5]+a[6]+a[7]+a[8];
        if(i==j&&j==k)
            total++;
    }
    public static void Perm(int a[],int k){
        if(k==a.length){
            test(a);
            return;
        }else{
            for(int i=k;i<a.length;i++){
                {int r=a[i];a[i]=a[k];a[k]=r;}
                Perm(a,k+1);
                {int r=a[i];a[i]=a[k];a[k]=r;}
            }
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int a[]={1,2,3,4,5,6,7,8,9};
        Perm(a,0);
        System.out.print(total/6);//这里其实是count/3/2,除以3是排除了旋转,除以2是排除了镜像
    }
}

三、承压计算

标题:承压计算

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

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

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

思路如下:
一共30行包括下面的电子秤。

当题目的数据较多时,可以从控制台进行输入,将其存放在数组当中即可。
切记将其构造成数组来进行计算,这样很浪费时间。

代码如下:

package s_3;

import java.util.Scanner;

public class Main {

    /*
     *答案为:72665192664
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin=new Scanner(System.in);
        double a[][]=new double[30][30];
        for(int i=0;i<=28;i++){
            for(int j=0;j<=i;j++){
                a[i][j]=cin.nextDouble();
            }
        }

        for(int i=1;i<=29;i++){
            for(int j=0;j<=i;j++){
            //1).当为每一行的第一个元素时,只能加上其右上角元素的一半;
                if(j==0)
                    a[i][j]+=a[i-1][j]/2.0;
            //2).当为每一行的最后一个元素时,只能加上其左上角的元素的一半。  
                else if(i==j)
                    a[i][j]+=a[i-1][j-1]/2.0;
            //3).当为除了前两种情况之外的情况后,可以加上其左上角元素的一半和其右上角元素的一半。   
                else
                    a[i][j]=a[i][j]+(a[i-1][j-1]+a[i-1][j])/2.0;
            }
        }
        /*
         *下面为一个标准:
         *读数最小的电子秤的示数为:2086458231
         *当为min=3.8863313030451536时,读数为2086458231
         *当为max=135.34946863353252时,读数为?
         *通过计算可得为:7.2665192664E10
         */
        double min=a[29][0];
        double max=a[29][0];
        for(int j=1;j<=29;j++){
            if(a[29][j]<min)
                min=a[29][j];
            if(a[29][j]>max)
                max=a[29][j];

        }
        System.out.println(min);
        System.out.println(max);
        System.out.println(2086458231/min*max);

        System.out.println();
        for(int i=0;i<=29;i++){
            for(int j=0;j<=i;j++){
                System.out.print(a[i][j]+" ");
                if(j==i)                    
                    System.out.println();
            }
        }

    }

}

结果:(min、max、2086458231/min*max)
这里写图片描述
五、取数位(简单就不写思路了)

标题:取数位

求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 ______________________;  //填空
    }

    public static void main(String[] args)
    {
        int x = 23513;
        //System.out.println(len(x));
        System.out.println(f(x,3));
    }
}

对于题目中的测试数据,应该打印5。

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

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

代码如下:

package s_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));
    }
}

六、最大公共子串


标题:最大公共子串

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

比如:"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);
    }
}


注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。

代码如下:

package s_6;
/*
 * 答案:a[i][j]=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;
        //a.length代表数组的行数。
        for(int i=1; i<a.length; i++){
            //a[i].length代表列数。
            for(int j=1; j<a[i].length; j++){
                if(c1[i-1]==c2[j-1]) {
                    //数组a[i][j]的含义是到字符串1的i位置和字符串2的j位置为止的最大公共子串的长度。
                    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");
        //int n = f("ABCBDAB", "BDCABA");

        System.out.println(n);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36717487/article/details/79770121