第六届蓝桥杯Java B组决赛试题

1.标题:分机号


X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位。比如:


751,520,321 都满足要求,而,
766,918,201 就不符合要求。


现在请你计算一下,按照这样的规定,一共有多少个可用的3位分机号码?


请直接提交该数字,不要填写任何多余的内容。



答案:120

import java.util.*;
public class Main {
    public static boolean check(int n)
    {
        int a1=n%10;
        int a2=n/10%10;
        int a3=n/100;
        if(a1!=a2 && a2!=a3 && a3!=a1 && a3>a2 && a2>a1)
        {
            return true;
        }
        else
            return false;
    }
    public static void main(String args[]) {
        int count=0;
        for(int i=100;i<=999;i++)
        {
            if(check(i))
            {
                count++;
            }
        }
        System.out.println(count);
    }
}
2.标题:五星填数


如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
要求每条直线上数字和相等。

第六届蓝桥杯Java B组决赛试题_第1张图片
如图就是恰当的填法。


请你利用计算机搜索所有可能的填法有多少种。
注意:旋转或镜像后相同的算同一种填法。


请提交表示方案数目的整数,不要填写任何其它内容。


答案:12

思路:暴力全排,最后除 旋转*对称 = 5*2 = 10.

import java.util.*;
public class Main {
    static int count=0;
    public static boolean check(int a[])
    {
        int r[]=new int[5];
        r[0]=a[0]+a[3]+a[6]+a[9];
        r[1]=a[9]+a[7]+a[5]+a[1];
        r[2]=a[1]+a[2]+a[3]+a[4];
        r[3]=a[4]+a[6]+a[7]+a[8];
        r[4]=a[8]+a[5]+a[2]+a[0];

        for(int i=0;i<4;i++)
        {
            for(int j=i+1;j<5;j++)
            {
                if(r[i]!=r[j])
                {
                    return false;
                }
            }
        }
        return true;
    }
    public static void allSort(int a[],int s,int e)
    {
        if(s==e)
        {
            System.out.println(Arrays.toString(a));
            if(check(a))
            {
                count++;
            }
            return;
        }

        for(int i=s;i<=e;i++)
        {
            swap(a,s,i);
            allSort(a,s+1,e);
            swap(a,s,i);
        }
    }

    public static void swap(int a[],int s,int e)
    {
        int temp=a[s];
        a[s]=a[e];
        a[e]=temp;
    }
    public static void main(String args[]) {
        int array[]={1,2,3,4,5,6,8,9,10,12};
        allSort(array,0,array.length-1);
        System.out.println(count/10);
    }
}

3.

标题:显示二叉树


排序二叉树的特征是:
某个节点的左子树的所有节点值都不大于本节点值。
某个节点的右子树的所有节点值都不小于本节点值。


为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二叉树的结构来。

[java]  view plain  copy
  1. class BiTree  
  2. {  
  3.     private int v;  
  4.     private BiTree l;  
  5.     private BiTree r;  
  6.       
  7.     public BiTree(int v){  
  8.         this.v = v;  
  9.     }  
  10.       
  11.     public void add(BiTree the){  
  12.         if(the.v < v){  
  13.             if(l==null) l = the;  
  14.             else l.add(the);  
  15.         }  
  16.         else{  
  17.             if(r==null) r = the;  
  18.             else r.add(the);  
  19.         }  
  20.     }  
  21.       
  22.     public int getHeight(){  
  23.         int h = 2;  
  24.         int hl = l==null0 : l.getHeight();  
  25.         int hr = r==null0 : r.getHeight();  
  26.         return h + Math.max(hl,hr);  
  27.     }  
  28.       
  29.     public int getWidth(){  
  30.         int w = (""+v).length();  
  31.         if(l!=null) w += l.getWidth();  
  32.         if(r!=null) w += r.getWidth();  
  33.         return w;  
  34.     }  
  35.       
  36.     public void show(){  
  37.         char[][] buf = new char[getHeight()][getWidth()];  
  38.         printInBuf(buf, 00);  
  39.         showBuf(buf);  
  40.     }  
  41.       
  42.     private void showBuf(char[][] x){  
  43.         for(int i=0; i
  44.             for(int j=0; j
  45.                 System.out.print(x[i][j]==0' ':x[i][j]);  
  46.             System.out.println();  
  47.         }  
  48.     }  
  49.       
  50.     private void printInBuf(char[][] buf, int x, int y){  
  51.         String sv = "" + v;  
  52.           
  53.         int p1 = l==null? x : l.getRootPos(x);  
  54.         int p2 = getRootPos(x);  
  55.         int p3 = r==null? p2 : r.getRootPos(p2+sv.length());  
  56.           
  57.         buf[y][p2] = '|';  
  58.         for(int i=p1; i<=p3; i++) buf[y+1][i]='-';  
  59.         for(int i=0; i//填空位置  
  60.         if(p11][p1] = '/';  
  61.         if(p3>p2) buf[y+1][p3] = '\\';  
  62.           
  63.         if(l!=null) l.printInBuf(buf,x,y+2);  
  64.         if(r!=null) r.printInBuf(buf,p2+sv.length(),y+2);  
  65.     }  
  66.       
  67.     private int getRootPos(int x){  
  68.         return l==null? x : x + l.getWidth();  
  69.     }  
  70. }  
  71.   
  72. public class Main  
  73. {  
  74.     public static void main(String[] args)  
  75.     {         
  76.         BiTree tree = new BiTree(500);  
  77.         tree.add(new BiTree(200));  
  78.         tree.add(new BiTree(509));  
  79.         tree.add(new BiTree(100));  
  80.         tree.add(new BiTree(250));  
  81.         tree.add(new BiTree(507));  
  82.         tree.add(new BiTree(600));  
  83.         tree.add(new BiTree(650));  
  84.         tree.add(new BiTree(450));  
  85.         tree.add(new BiTree(510));  
  86.         tree.add(new BiTree(440));  
  87.         tree.add(new BiTree(220));        
  88.         tree.show();          
  89.     }  
  90. }  
    对于上边的测试数据,应该显示出:
    
    (如有对齐问题,请参考【图1.png】)

请分析程序逻辑,填写划线部分缺失的代码。


注意,只填写缺少的部分,不要填写已有的代码或符号,也不要加任何说明文字。


答案:buf[y+1][p2+i] = sv.charAt(i)

4.

标题:穿越雷区


X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?


已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -


坦克车只能水平或垂直方向上移动到相邻的区。


数据格式要求:


输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。


要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1


例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -


则程序应该输出:
10


资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗  < 2000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。


所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。

思路:简单DFS

[java]  view plain  copy
  1. import java.util.*;  
  2. public class Main {  
  3.     static int n;  
  4.     static int map[][];  
  5.     static boolean vis[][];  
  6.     static int nx,ny,tx,ty;  
  7.     static int x[]={0,0,1,-1};  
  8.     static int y[]={1,-1,0,0};  
  9.     static int res=100000000;  
  10.   
  11.     public static void dfs(int px,int py,int step)  
  12.     {  
  13.         if(px==tx && py==ty)  
  14.         {  
  15.             if (step
  16.             {  
  17.                 res=step;  
  18.             }  
  19.             return;  
  20.         }  
  21.   
  22.         for(int i=0;i<4;i++)  
  23.         {  
  24.             if(!vis[px+x[i]][py+y[i]] && (map[px][py]==0 || map[px+x[i]][py+y[i]]==0 ||map[px+x[i]][py+y[i]]==-map[px][py]))  
  25.             {  
  26.                 vis[px+x[i]][py+y[i]]=true;  
  27.                 dfs(px+x[i],py+y[i],step+1);  
  28.                 vis[px+x[i]][py+y[i]]=false;  
  29.             }  
  30.         }  
  31.     }  
  32.   
  33.     public static void main(String args[]){  
  34.         Scanner in=new Scanner(System.in);  
  35.   
  36.         n=in.nextInt();  
  37.         map=new int[n+2][n+2];  
  38.         vis=new boolean[n+2][n+2];  
  39.   
  40.         for(int i=0;i<=n+1;i++)  
  41.         {  
  42.             vis[0][i]=true;  
  43.             vis[i][0]=true;  
  44.             vis[n+1][i]=true;  
  45.             vis[i][n+1]=true;  
  46.         }  
  47.   
  48.         for(int i=1;i<=n;i++)  
  49.         {  
  50.             for(int j=1;j<=n;j++)  
  51.             {  
  52.                 String str=in.next();  
  53.                 if(str.charAt(0)=='A')  
  54.                 {  
  55.                     map[i][j]=0;  
  56.                     nx=i;ny=j;  
  57.                 }  
  58.                 if(str.charAt(0)=='B')  
  59.                 {  
  60.                     map[i][j]=0;  
  61.                     tx=i;ty=j;  
  62.                 }  
  63.                 if(str.charAt(0)=='+')  
  64.                 {  
  65.                     map[i][j]=1;  
  66.                 }  
  67.                 if(str.charAt(0)=='-')  
  68.                 {  
  69.                     map[i][j]=-1;  
  70.                 }  
  71.             }  
  72.         }  
  73.   
  74.         dfs(nx,ny,0);  
  75.   
  76.         System.out.println(res);  
  77.   
  78.     }  
  79.   
  80.   
  81. }  
5.

标题:表格计算


某次无聊中, atm 发现了一个很老的程序。这个程序的功能类似于 Excel ,它对一个表格进行操作。
不妨设表格有 n 行,每行有 m 个格子。
每个格子的内容可以是一个正整数,也可以是一个公式。
公式包括三种:
1. SUM(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的和。
2. AVG(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的平均数。
3. STD(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的标准差。


标准差即为方差的平方根。
方差就是:每个数据与平均值的差的平方的平均值,用来衡量单个数据离开平均数的程度。


公式都不会出现嵌套。


如果这个格子内是一个数,则这个格子的值等于这个数,否则这个格子的值等于格子公式求值结果。


输入这个表格后,程序会输出每个格子的值。atm 觉得这个程序很好玩,他也想实现一下这个程序。


「输入格式」
第一行两个数 n, m 。
接下来 n 行输入一个表格。每行 m 个由空格隔开的字符串,分别表示对应格子的内容。
输入保证不会出现循环依赖的情况,即不会出现两个格子 a 和 b 使得 a 的值依赖 b 的值且 b 的值依赖 a 的值。


「输出格式」
输出一个表格,共 n 行,每行 m 个保留两位小数的实数。
数据保证不会有格子的值超过 1e6 。


「样例输入」
3 2
1 SUM(2,1:3,1)
2 AVG(1,1:1,2)
SUM(1,1:2,1) STD(1,1:2,2)


「样例输出」
1.00 5.00
2.00 3.00
3.00 1.48


「数据范围」
对于 30% 的数据,满足: n, m <= 5
对于 100% 的数据,满足: n, m <= 50



资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗  < 2000ms



请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。


所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。

import java.util.Scanner;  
  
public class Main  
{  
    static String[][] str = new String[50][50];  
    static double[][] d = new double[50][50];  
    static int n, m;  
    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);  
        n = in.nextInt();  
        m = in.nextInt();  
        for (int i = 1; i <= n; i++) {  
            for (int j = 1; j <= m; j++) {  
                String c = in.next();  
                str[i][j] = c;  
            }  
        }  
        for (int i = 1; i <= n; i++) {  
            for (int j = 1; j <= m; j++) {  
                if (str[i][j].charAt(0) < '0' || str[i][j].charAt(0) > '9') {  
                    d[i][j] = func(str[i][j], i, j);  
                } else {  
                    d[i][j] = Double.valueOf(str[i][j]);  
                }  
            }  
        }  
        for (int i = 1; i <= n; i++) {  
            for (int j = 1; j < m; j++) {  
                System.out.printf("%.2f ",d[i][j]);  
            }  
            System.out.printf("%.2f\n", d[i][m]);  
        }  
    }  
      
    /** 
     * 这里必须采用函数的方式将这里包起来,因为有的sum处理里面还会包含sum,所以需要再次调用这里的函数。 
     * */  
    private static double func(String string, int i, int j) {  
        // TODO Auto-generated method stub  
        int subce[] = sub(str[i][j]);  
        if (str[i][j].substring(0, 3).equals("SUM")) {  
            return sum(subce);  
        } else if (str[i][j].substring(0, 3).equals("AVG")) {  
            return avg(subce);  
        } else if (str[i][j].substring(0, 3).equals("STD")) {  
            return std(subce);  
        } else {  
            return -1;  
        }  
    }  
    /** 
     * 三个表达式的计算都很简单 
     * 在求avg和std中,要有注意如何求四个坐标所围矩阵中单元格的个数,可以使用(x2-x1+1)*(y2-y1+1),也可以直接计数 
     * 由于每个计算都有可能出现类似sum的计算中包含sum的情况,所以要进行判断,再次调用func() 
     * */  
    private static double sum(int[] ce2) {  
        // TODO Auto-generated method stub  
        double cnt = 0.0;  
        for (int i = ce2[1]; i <= ce2[3]; i++) {  
            for (int j = ce2[2]; j <= ce2[4]; j++) {  
                if (str[i][j].charAt(0) < '0' || str[i][j].charAt(0) > '9') {  
                    cnt += func(str[i][j], i, j);  
                } else {  
                    cnt += Double.valueOf(str[i][j]);  
                }  
            }  
        }  
        return cnt;  
    }  
      
    private static double avg(int[] ce2) {  
        // TODO Auto-generated method stub  
        double cnt = 0.0;  
        int q = 0;  
        for (int i = ce2[1]; i <= ce2[3]; i++) {  
            for (int j = ce2[2]; j <= ce2[4]; j++) {  
                if (str[i][j].charAt(0) < '0' || str[i][j].charAt(0) > '9') {  
                    cnt += func(str[i][j], i, j);  
                } else {  
                    cnt += Double.valueOf(str[i][j]);  
                }  
                q++;  
            }  
        }  
        return cnt/q;  
    }  
      
    private static double std(int[] ce2) {  
        // TODO Auto-generated method stub  
        double cnt = 0.0;  
        int q = 0;  
        double x = avg(ce2);  
        for (int i = ce2[1]; i <= ce2[3]; i++) {  
            for (int j = ce2[2]; j <= ce2[4]; j++) {  
                if (str[i][j].charAt(0) < '0' || str[i][j].charAt(0) > '9') {  
                    cnt += Math.pow(func(str[i][j], i, j) - x, 2);  
                } else {  
                    cnt += Math.pow(Double.valueOf(str[i][j]) - x, 2);  
                }  
                q++;  
            }  
        }  
        return Math.sqrt(cnt/q);  
    }  
      
    /*** 
     * 下面是对表达式进行截取拆分获取x1,x2,y1,y2的过程 
     * 由于出现了两次",",所以在获取的过程中要注意,第二个","的获取可以先将前一个","连同之前的内容截去,然后再进行一次截取 
     *   
     */  
    private static int[] sub(String s) {  
        // TODO Auto-generated method stub  
        int[] ce = new int[5];  
        for (int i = 0; i < ce.length; i++) {  
            ce[i] = 0;  
        }  
      
        int befKuohao = s.indexOf('(');  
        int firstDouhao = s.indexOf(',');  
        int maohao = s.indexOf(':');  
        int secDouhao = s.substring((s.indexOf(',')+1)).indexOf(',') + (s.indexOf(',')+1);  
        int aftKuohao = s.indexOf(')');  
        ce[1] = Integer.valueOf(s.substring(befKuohao+1, firstDouhao));  
        ce[2] = Integer.valueOf(s.substring(firstDouhao+1, maohao));  
        ce[3] = Integer.valueOf(s.substring(maohao+1, secDouhao));  
        ce[4] = Integer.valueOf(s.substring(secDouhao+1, aftKuohao));  
        return ce;  
    }  
}  

6.



标题:铺瓷砖


为了让蓝桥杯竞赛更顺利的进行,主办方决定给竞赛的机房重新铺放瓷砖。机房可以看成一个n*m的矩形,而这次使用的瓷砖比较特别,有两种形状,如【图1.png】所示。在铺放瓷砖时,可以旋转。
 
主办方想知道,如果使用这两种瓷砖把机房铺满,有多少种方案。


【输入格式】
输入的第一行包含两个整数,分别表示机房两个方向的长度。


【输出格式】
输出一个整数,表示可行的方案数。这个数可能很大,请输出这个数除以65521的余数。


【样例输入1】
4 4
【样例输出1】
2
【样例说明1】
这两种方案如下【图2.png】所示:
 
【样例输入2】
2 6
【样例输出2】
4
【数据规模与约定】
对于20%的数据,1<=n, m<=5。
对于50%的数据,1<=n<=100,1<=m<=5。
对于100%的数据,1<=n<=10^15,1<=m<=6。
 
资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗  < 8000ms




请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。


所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。


思路:应该是先拆分砖块数,如12=3*4=4*3,再分别考察每种情况是否可行,但是题目貌似把旋转对称的方案也算作不同,先占坑。



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