试题A:分机号
X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,
所有号码必须是降序排列,且不能有重复的数位。比如:
751,520,321 都满足要求,而,
766,918,201 就不符合要求。
现在请你计算一下,按照这样的规定,一共有多少个可用的3位分机号码?
请直接提交该数字,不要填写任何多余的内容。
【思路】倒序初始化数组9-0,再进行元素抽取全排列
答案:120
public class Main1 {
static int[] a1 = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, a2 = new int[3];
static int count = 0;
public static void main(String[] args) {
f(0, 0);
System.out.println(count);
}
static void f(int c, int p) {
if (p == a2.length) {
count ++;
return;
}
for (int i = c; i < a1.length; i++) {
a2[p] = a1[i];
f(i + 1, p + 1);
}
}
}
试题B:五星填数
如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
要求每条直线上数字和相等。
如图就是恰当的填法。
请你利用计算机搜索所有可能的填法有多少种。
注意:旋转或镜像后相同的算同一种填法。
请提交表示方案数目的整数,不要填写任何其它内容。
【思路】全排列,下图红色数字表示数组下标
答案12
import java.util.Arrays;
public class Main2 {
static int[] a = {1, 2, 3, 4, 5, 6, 8, 9, 10, 12};
static int count = 0;
public static void main(String[] args) {
f(0);
System.out.println(count / 5 / 2);
}
static void f(int p) {
if (p == a.length) {
// 6 8 10 12 9 5 3 1 4 2
if (check()) {
count ++;
System.out.println(Arrays.toString(a));
return;
}
}
for (int i = p; i < a.length; i++) {
swap(i, p);
f(1 + p);
swap(i, p);
}
}
static boolean check() {
int b = a[0] + a[5] + a[6] + a[2];
int c = a[2] + a[7] + a[8] + a[4];
int d = a[4] + a[9] + a[5] + a[1];
int e = a[1] + a[6] + a[7] + a[3];
int f = a[3] + a[8] + a[9] + a[0];
if (b == c && c == d && d == e && e == f) {
return true;
}
return false;
}
static void swap(int i, int p) {
int t = a[i];
a[i] = a[p];
a[p] = t;
}
}
试题C:显示二叉树
排序二叉树的特征是:
某个节点的左子树的所有节点值都不大于本节点值。
某个节点的右子树的所有节点值都不小于本节点值。
为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二叉树的结构来。
对于上边的测试数据,应该显示出:
请分析程序逻辑,填写划线部分缺失的代码。
注意,只填写缺少的部分,不要填写已有的代码或符号,也不要加任何说明文字。
答案:buf[y + 1][p2 + i] = sv.charAt(i);
试题D:穿越雷区
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递归,每递归步数+1,回溯步数-1。
- 若当前为起点,下一步可以任意走。
- 若当前为’+’,下一步必须为’-’。
- 若当前为’-’,下一步必须为’+’。
- 到达终点B时,判断步数是否为最小。
import java.util.Scanner;
public class Main4 {
static char[][] arr;
static int[][] xy = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
static boolean[][] vis;
static int n = 0, count = 0, min;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
sc.nextLine();
// 初始化地图
arr = new char[n][n];
// 记录踩过的轨迹
vis = new boolean[n][n];
// 最少移动步数
min = n * n;
for (int i = 0; i < n; i++) {
String[] s = sc.nextLine().split(" ");
for (int j = 0; j < n; j++) {
arr[i][j] = s[j].charAt(0);
}
}
sc.close();
f();
System.out.println(min == n * n ? -1 : min);
}
static void f() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (arr[i][j] == 'A' && !vis[i][j]) {
vis[i][j] = true;
dfs(i, j);
return;
}
}
}
}
static void dfs(int x, int y) {
// 四周探测
for (int i = 0; i < xy.length; i++) {
int o = x + xy[i][0];
int p = y + xy[i][1];
// 若没有越界且没有走过
if (o >= 0 && o < n && p >= 0 && p < n && !vis[o][p]) {
// 若没有到达终点B继续递归
if (arr[o][p] != 'B') {
// 若当前坐标为起点A
if (arr[x][y] == 'A') {
if (arr[o][p] == '-' || arr[o][p] == '+') {
dg(o, p);
}
} else if (arr[x][y] == '-' && arr[o][p] == '+') {
dg(o, p);
} else if (arr[x][y] == '+' && arr[o][p] == '-') {
dg(o, p);
}
} else {
// 若到达终点B
if (count < min) {
min = count;
// 将最后一步终点B加上
min ++;
}
}
}
}
}
static void dg(int o, int p) {
// 每走一步加一
count ++;
// 标记已走过
vis[o][p] = true;
dfs(o, p);
// 回溯减一
count --;
// 标记未走过
vis[o][p] = false;
}
}
试题E:表格计算
待更
试题F:铺瓷砖
待更