题目说明
人们聚集在某个活动会场上,根据到达会场的顺序排成一排等待入场。
假设你是活动的主办人员,想把人们从队列的某个位置分成两组。
求男性 20 人、女性 10 人的情况下,
有多少种到场顺序会导致无论怎么分组都没法实现任一组的男女人数均等?(原书表述有歧义,此处已修改)
即两组内的男女数量均不相同。
思路
如上图所示,
在10行20列的网格中,每一个交叉点的坐标都表示男、女的数量
x增加1,表示到一个男生;y增加1,表示到一个女生。
第一组:x和y相等的点标为"红点",
第二组:(20-x)和(10-y)相等的点也标记为"红点"
假设左下角原点为A点;右上角的点记为B点
则题目可以转化为:求从A点到B点的最短路径中,不经过"红点"的路线有多少条
也就是求解A点到B点在蓝色区域的最短路径的数量(所以人数多的一方要先到,也就是为啥x初始值为1)
代码
public static int count = 0; // 统计路线数量
public static void main(String[] args) {
int x = 1; // 男生数量(人数多的那一方,必须是人数多的那一方先来,否则总能让第一组的男女人数相等)
int y = 0; // 女生数量(人数少的那一方)
int xMax = 20; // 男生数量上限
int yMax = 10; // 女生数量上限
move(x,y,xMax,yMax);
System.out.println("count = " + count);
}
/**
* 因为是最短路径,所以不能走回头路:即要么往上,要么往右。
* @param x 当前男生的数量
* @param y 当前女生的数量
* @param xMax 男生数量上限
* @param yMax 女生数量上限
*/
public static void move(int x, int y, int xMax, int yMax){
// 到达B点
if(x == xMax && y == yMax){
count ++; // 正确结果+1
return ;
}
// 经过"红点",直接返回
if(x == y || (xMax - x) == (yMax - y)){
return ;
}
// 右移:来一个男生
if(x < xMax){
move(x+1,y,xMax,yMax);
}
// 上移:来一个女生
if(y < yMax){
move(x,y+1,xMax,yMax);
}
}
结果
count = 2417416