第一题:
标题:分机号
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; ip2) 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
接下来就是我填进去之后运行的结果:
第四题:
标题:穿越雷区
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);
}
}
作者很菜,如有不足,请指教