程序员的算法趣题:Q09 落单的男女(Java版)

题目说明

人们聚集在某个活动会场上,根据到达会场的顺序排成一排等待入场。
假设你是活动的主办人员,想把人们从队列的某个位置分成两组。
求男性 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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值