Java软件开发B组
1
X星球愤怒的小鸟喜欢撞火车!
一根平直的铁轨上两火车间相距1000 米
两火车 (不妨称A和B) 以时速 10米/秒 相对行驶。
愤怒的小鸟从A车出发,时速50米/秒,撞向B车,
然后返回去撞A车,再返回去撞B车,如此往复....
两火车在相距1米处停车。
问:这期间愤怒的小鸟撞 B 车多少次?
注意:需要提交的是一个整数(表示撞B车的次数),不要填写任何其它内容。
/**
* 思路:
* 小鸟的飞行
* 小鸟从A到B花费时间t1,A到B此时距离s1
* (50+10)*t1=s1
* 小鸟从B到A花费时间t2,B到A此时距离s2
* s2=s1-(10+10)t1
* 由上式可知:
* 每次小鸟和A或B火车相撞A到B的距离变化为:
* s=s-s/3;
*
* 由于小鸟是从A出发,先撞的B。撞车总次数:n 所以:
* 撞A的次数为:n整除2
* 撞B的次数为:(n+1)整除2
* @author 王孙悟空
*
*/
public class Main {
public static void main(String[] args) {
double A_B = 1000;
int n = 0;
while (A_B >= 1) {
A_B -= A_B / 3;
n++;
}
System.out.println((n + 1) / 2);
}
}
运行结果:9
2
反幻方
我国古籍很早就记载着
2 9 4
7 5 3
6 1 8
这是一个三阶幻方。每行每列以及对角线上的数字相加都相等。
下面考虑一个相反的问题。
可不可以用 1~9 的数字填入九宫格。
使得:每行每列每个对角线上的数字和都互不相等呢?
这应该能做到。
比如:
9 1 2
8 4 3
7 5 6
你的任务是搜索所有的三阶反幻方。并统计出一共有多少种。
旋转或镜像算同一种。
比如:
9 1 2
8 4 3
7 5 6
7 8 9
5 4 1
6 3 2
2 1 9
3 4 8
6 5 7
等都算作同一种情况。
请提交三阶反幻方一共多少种。这是一个整数,不要填写任何多余内容。
import java.util.HashSet;
/**
* 思路:先全排列,再判断是否符合条件
* @author 王孙悟空
*
*/
public class Main {
static int sum=0;
public static void main(String[] args) {
int ary[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
fun(ary, 0);
System.out.println(sum/8);//旋转有四种 镜像有两种
}
/**
* 全排列算法
* @param ary
* @param k
*/
static void fun(int ary[], int k) {
//递归出口。
if(k>=ary.length){
if(check(ary)){
sum++;
}
return;
}
int temp;
for (int i = k; i < ary.length; i++) {
{//试探交换位置
temp = ary[i];
ary[i] = ary[k];
ary[k] = temp;
}
//递归
fun(ary,k+1);
{//回溯
temp = ary[i];
ary[i] = ary[k];
ary[k] = temp;
}
}
}
/**
* 使用HashSet判断是否符合要求,利用了HashSet里的数据都不重复的特性。
* @param ary
* @return
*/
static boolean check(int ary[]){
HashSet<Integer> pc=new HashSet<Integer>();
pc.add(ary[0]+ary[1]+ary[2]);
pc.add(ary[3]+ary[4]+ary[5]);
pc.add(ary[6]+ary[7]+ary[8]);
pc.add(ary[0]+ary[3]+ary[6]);
pc.add(ary[1]+ary[4]+ary[7]);
pc.add(ary[2]+ary[5]+ary[8]);
pc.add(ary[0]+ary[4]+ary[8]);
pc.add(ary[2]+ary[4]+ary[6]);
if(pc.size()==8)
return true;
return false;
}
}
运行结果:3120
3
打靶
小明参加X星球的打靶比赛。
比赛使用电子感应计分系统。其中有一局,小明得了96分。
这局小明共打了6发子弹,没有脱靶。
但望远镜看过去,只有3个弹孔。
显然,有些子弹准确地穿过了前边的弹孔。
不同环数得分是这样设置的:
1,2,3,5,10,20,25,50
那么小明的6发子弹得分都是多少呢?有哪些可能情况呢?
下面的程序解决了这个问题。
仔细阅读分析代码,填写划线部分缺失的内容。
思路:认真分析知:
i表示的是第k环打中的次数。
所以当打中0次,洞不减少。
当打中多次,洞减少1
由此可见代码填空题并不是很难。
public class Main
{
static void f(int[] ta, int[] da, int k,int ho, int bu, int sc)
{
if(ho<0 || bu<0 || sc<0)return;
if(k==ta.length){
if(ho>0 || bu>0 || sc>0)return;
for(int i=0; i<da.length; i++){
for(int j=0; j<da[i]; j++)
System.out.print(ta[i] + " ");
}
System.out.println();
return;
}
for(int i=0; i<=bu; i++){
da[k] = i;
f(ta, da, k+1, ho-(i>0?1:0), bu-i, sc-ta[k]*i); //填空位置
}
da[k] = 0;
}
public static void main(String[] args)
{
int[] ta = {1,2,3,5,10,20,25,50};
int[] da = new int[8];
f(ta, da, 0, 3, 6, 96);
}
}
注意:只填写划线处缺少的内容,不要填写已有的代码或符号,也不要填写任何解释说明文字等。
4.路径之谜
小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。【如图1.png】所示。
按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 n 个靶子)
同一个方格只允许经过一次。但不必做完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图1.png中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
输入:
第一行一个整数N(0<N<20),表示地面有 N x N 个方格
第二行N个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行N个整数,空格分开,表示西边的箭靶上的数字(自北向南)
输出:
一行若干个整数,表示骑士路径。
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3....
比如,图1.png中的方块编号为:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
示例:
用户输入:
4
2 4 3 4
4 3 3 3
程序应该输出:
0 4 5 1 2 3 7 11 10 9 13 14 15
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
import java.util.ArrayList;
import java.util.Scanner;
/**
* 路径之谜:思路深度优先搜所加判断
* @author 王孙悟空
*/
public class Main {
// 存放北边的箭靶上的数字
static int ary1[];
// 存放西边的箭靶上的数字
static int ary2[];
// map代表地图
static int map[][];
// 东南西北四个方向
static int direct[] = { 1, 0, -1, 0, 1 };
// 存放方块编号
static ArrayList<Integer> result = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ary1 = new int[n];
ary2 = new int[n];
map = new int[n][n];
for (int i = 0; i < ary1.length; i++) {
ary1[i] = sc.nextInt();
}
for (int i = 0; i < ary2.length; i++) {
ary2[i] = sc.nextInt();
}
sc.close();
ary1[0]--;
ary2[0]--;
map[0][0] = -1;
result.add(0);
DFS(0, 0);
}
// 广度优先搜素
static void DFS(int x, int y) {
// 递归出口
if (x == ary1.length - 1 && y == ary1.length - 1) {
if (checked()) {
for (int i = 0; i < result.size(); i++) {
System.out.print(result.get(i) + " ");
}
return;
}
}
for (int i = 1; i < direct.length; i++) {
x += direct[i - 1];
y += direct[i];
// 检查是否可行
if (checkRange(x, y)) {
ary1[x]--;
ary2[y]--;
// 检查是否
if (checkArrow()) {
// 标记为-1表示已走过
map[y][x] = -1;
result.add(y * ary1.length + x);
DFS(x, y);
// 回溯
result.remove(Integer.valueOf(y * ary1.length + x));
map[y][x] = 0;
}
// 回溯
ary1[x]++;
ary2[y]++;
}
// 回溯
x -= direct[i - 1];
y -= direct[i];
}
}
/**
* 判断是否超出棋盘范围
*
* @param x
* @param y
* @return
*/
static boolean checkRange(int x, int y) {
if (x < 0 || y < 0 || x >= ary1.length || y >= ary1.length
|| map[y][x] == -1) {
return false;
}
return true;
}
/**
* //检查射上的箭,是否过多
*
* @return
*/
static boolean checkArrow() {
for (int i = 0; i < ary1.length; i++) {
if (ary1[i] < 0 || ary2[i] < 0) {
return false;
}
}
return true;
}
/**
* 检查是否符合最终要求
* @return
*/
static boolean checked() {
for (int i = 0; i < ary1.length; i++) {
if (ary1[i] != 0 || ary2[i] != 0) {
return false;
}
}
return true;
}
}