第一题:
标题:分机号
X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位。比如:
751,520,321 都满足要求,而,
766,918,201 就不符合要求。
现在请你计算一下,按照这样的规定,一共有多少个可用的3位分机号码?
请直接提交该数字,不要填写任何多余的内容。
自己发现蓝桥杯比较喜欢靠全排列这种东西,所以建议读者们去看看
这里其实题目意思很简单就是排三位数,三位数必选降序排列,其中又不能出现重复的位数,所以最简单的方法就是用三层for循环从0到9来开始,但是如果仔细想想其实是可以缩小一部分范围的,就比如最高位最低也要取2,这样210才成立,如果取2以下的,那么第三位就怎么也取不到了,又因为是降序无法重复,所以,第二层循环就要从前一层循环-1开始,依次这样,就可以缩短部分的范围,节省一部分的时间,思路就是这样,下面附上源代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class num01 { public static boolean panduan(int i,int j,int k) { boolean result=false; if(i>j&&j>k) result=true; return result; } public static void main(String[] args) throws IOException { StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out)); int count=0; for(int i=9;i>1;i--) { for(int j=i-1;j>0;j--) { for(int k=j-1;k>-1;k--) { if(panduan(i, j, k)) { //out.println(i+""+j+""+k); count++; } } } } out.println(count); out.flush(); } }
第二题:
标题:五星填数
如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
要求每条直线上数字和相等。
如图就是恰当的填法。
请你利用计算机搜索所有可能的填法有多少种。
注意:旋转或镜像后相同的算同一种填法。
请提交表示方案数目的整数,不要填写任何其它内容。
这里我们的主要思路就是用数组来存储这些数据,但是该用怎样的数组呢,这里我们可以考虑用一维数组来存储,这里我们就需要理解如何来存储呢,我们不妨用下面的图标来存储,我在上面标注就是该数在数组中的下标
这样我们就可以定向的通过下标求和来判断是否符合题意,接下来的一步就是又像第一题一样,又要进行全排列了,这里的全排列就是比较标准的全排列了,这里作者就直接贴源代码解释了
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class num02 { public static int count=0; public static int []num= {1,2,3,4,5,6,8,9,10,12}; public static void fullsort(int []num,int i) { if(i==num.length) { if(panduan(num)) count++; return; } for(int j=i;j<num.length;j++) { swap(num, i, j); fullsort(num, i+1); swap(num, i, j); } } public static boolean panduan(int []num) { boolean result=true; int []sum=new int [5]; sum[0]=num[0]+num[2]+num[5]+num[8]; sum[1]=num[0]+num[3]+num[6]+num[9]; sum[2]=num[1]+num[2]+num[3]+num[4]; sum[3]=num[1]+num[5]+num[7]+num[9]; sum[4]=num[4]+num[6]+num[7]+num[8]; for(int i=0;i<4;i++) { if(sum[i]!=sum[i+1]) { result=false; break; } } return result; } public static void swap(int []num,int i,int j) { int temp=num[i]; num[i]=num[j]; num[j]=temp; } public static void main(String[] args) throws IOException { StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out)); fullsort(num, 0); out.println(count/10);//圈重点了,这里一开始自己只是/5主要因为自己当时只想到了五角星的旋转,那样的话,一组值可以旋转5次,那样其实都是重复的 //但之后才知道/10的意思,意思是一个五角星可以有五个顶点,每个顶点都有两条边,这两条边进行镜像只够又能形成一个,但是形成之后的哪一个是不算的 //所以这样算起来的确应该/10 out.flush(); } }
最后需要注意的就是最后的结果需要/10,原因作者也已经写在代码的注释当中了
第三题:
标题:显示二叉树
排序二叉树的特征是:
某个节点的左子树的所有节点值都不大于本节点值。
某个节点的右子树的所有节点值都不小于本节点值。
为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二叉树的结构来。
class BiTree { private int v; private BiTree l; private BiTree r;
public BiTree(int v){ this.v = v; } public void add(BiTree the){ if(the.v < v){ if(l==null) l = the; else l.add(the); } else{ if(r==null) r = the; else r.add(the); } } public int getHeight(){ int h = 2; int hl = l==null? 0 : l.getHeight(); int hr = r==null? 0 : r.getHeight(); return h + Math.max(hl,hr); } public int getWidth(){ int w = (""+v).length(); if(l!=null) w += l.getWidth(); if(r!=null) w += r.getWidth(); return w; } public void show(){ char[][] buf = new char[getHeight()][getWidth()]; printInBuf(buf, 0, 0); showBuf(buf); } private void showBuf(char[][] x){ for(int i=0; i<x.length; i++){ for(int j=0; j<x[i].length; j++) System.out.print(x[i][j]==0? ' ':x[i][j]); System.out.println(); } } private void printInBuf(char[][] buf, int x, int y){ String sv = "" + v; int p1 = l==null? x : l.getRootPos(x); int p2 = getRootPos(x); int p3 = r==null? p2 : r.getRootPos(p2+sv.length()); buf[y][p2] = '|'; for(int i=p1; i<=p3; i++) buf[y+1][i]='-'; for(int i=0; i<sv.length(); i++) ________________________________; //填空位置 if(p1<p2) buf[y+1][p1] = '/'; if(p3>p2) buf[y+1][p3] = '\\'; if(l!=null) l.printInBuf(buf,x,y+2); if(r!=null) r.printInBuf(buf,p2+sv.length(),y+2); } private int getRootPos(int x){ return l==null? x : x + l.getWidth(); }
这里的重点就是先看懂这里面的几个重要的函数的意思,
这个函数是获取当前节点所在的整行的宽度:
public int getWidth(){ int w = (""+v).length(); if(l!=null) w += l.getWidth(); if(r!=null) w += r.getWidth(); return w; }