第一题: 标题:分机号
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; }
这个函数是用来获取当前节点的左边的宽度:
private int getRootPos(int x){ return l==null? x : x + l.getWidth(); }
之后我们可以通过这两行代码结合图片知道: buf[y][p2] = ‘|’; for(int i=p1; i<=p3; i++) buf[y+1][i]=’-’; 第y行只用来表示|符号 第y+1行用来表示/和----和根节点 p1的位置就代表左孩子结点的位置,p2代表右孩子结点的位置。 又通过分析填空之前的范围for(int i=0; i<sv.length(); i++)可以发现刚好是根节点的这个字的长度,又结合for(int i=p1; i<=p3; i++) buf[y+1][i]=’-’;可以知道原先是将整个范围内圈赋值为—,之后通过我们要填的这段代码将根节点的值赋进去所以分析得出,最后填的代码应该是;buf[y+1][p2+i]=sv.charAt(i); 接下来就是我填进去之后运行的结果:
第四题: 标题:穿越雷区
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。 某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。 例如:
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100 接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。 A,B都只出现一次。
要求输出一个整数,表示坦克从A区到B区的最少移动步数。 如果没有方案,则输出-1
例如: 用户输入:
则程序应该输出: 10
资源约定: 峰值内存消耗(含虚拟机) < 512M CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。 注意:主类的名字必须是:Main,否则按无效代码处理。
这里的主要思想就是深搜,以及剪枝这里剪枝可以通过下标的位置是否合乎范围来剪枝就比如:
if(i<0||i>n-1||j<0||j>n-1) return;
之后还有一点就是,只能走自己附近的点就是上下左右,所以我们可以通过一个数组来实现即:
public static int dir[][]=new int[][]{{-1,0},{0,1},{1,0},{0,-1}};
之后就比较简单了,以下是源代码;
import java.util.Scanner; public class num04 { public static int n; public static int i1,j1; public static int count=0; public static int min; public static boolean flag=false; public static char map[][]; public static int visit[][]; public static int dir[][]=new int[][]{{-1,0},{0,1},{1,0},{0,-1}}; public static void dfs(int i,int j) { int ii,jj; if(map[i][j]=='B') { flag=true; if(count<min) min=count; return ; } if(i<0||i>n-1||j<0||j>n-1) return; for(int k=0;k<4;k++) { ii=i+dir[k][0]; jj=j+dir[k][1]; if(ii<0||ii>n-1||jj<0||jj>n-1) continue; if(visit[ii][jj]==0&&map[ii][jj]!=map[i][j]) { visit[ii][jj]=1; count++; dfs(ii, jj); count--; visit[ii][jj]=0; } } } public static void main(String[] args) { Scanner sc=new Scanner(System.in); n=sc.nextInt(); sc.nextLine(); map=new char[n][n]; visit=new int [n][n]; min=n*n; String []str1=new String[n]; String []str2=new String[n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { visit[i][j]=0; } } for(int i=0;i<n;i++) { str1[i]=sc.nextLine(); str2[i]=str1[i].replace(" ", ""); } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { map[i][j]=str2[i].charAt(j); if(map[i][j]=='A') { i1=i; j1=j; visit[i1][j1]=1; } } } dfs(i1, j1); if(flag) System.out.println(min); else System.out.println(-1); } }
作者很菜,如有不足,请指教
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句