第七届Java软件开发B组

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;
	}
}





















 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值