张王李三家各有三个小孩。一天,三家的九个孩子在一起比赛短跑,规定不分年龄大小,跑第一得9分,跑第2得8分,依此类推。比赛结果各家的总分相同,且这
些孩子没有同时到达终点的,也没有一家的两个或三个孩子获得相连的名次。已知获第一名的是李家的孩子,获得第二的是王家的孩子。问获得最后一名的是谁家的
孩子?
*问题分析与算法设计
按题目的条件,共有1+2+3+...+9=45分,每家的孩子的得分应为15分。根据题意可知:获第一名的是李家的孩子,获第二名的是王家的孩子,则可推出:获第三名的一定是张家的孩子。
public class HaiziSaipao {
public static void main(String[] args) {
int[] count = new int[3];
int[] place = {0,1,2,0,0,0,0,0,0};// 记录排名情况,初试状态是"李家,王家,张家。。。"
count[0] = count[1] = count[2] = 1;// 记录各家多少孩子已经算出,初试状态是李家,王家,张家各一个孩子已经得出
method(place, 3, count);
}
static String[] home = { "李家", "王家", "张家" };
static int A = 0, B = 1, C = 2; // 使用数字方便地代表"李家,王家,张家"
/**
* 使用递归,从5到0,每个位置都试探遍历
*/
public static void method(int[] place, int position, int[] count) {
if (position >= 9) {
atry(place);// 找到一个数列,进行判断
return;
}
for (int child = A; child <= C; child++) {
// 保证当前排名和前一位不一样,保证每家的count不超过3
if (child != place[position - 1] && count[child] <= 3) {
count[child]++;
place[position] = child;
method(place, position + 1, count);
count[child]--;
}
}
}
/**
* 找到一个数列,验证是不是每家都是15分
*/
private static void atry(int[] place) {
int[] total = new int[3];
for (int i = 0; i < 9; i++) {
total[place[i]] += (i + 1);
if (total[place[i]] > 15) {
return;
}
}
// 找对了
for (int i = 0; i < 9; i++) {
System.out.print(home[place[i]] + " ");
}
System.out.println();
}
}
效果:
李家 王家 张家 王家 张家 李家 张家 李家 王家