学习小记--Python--6.2

我认为学语言要通过实践来加强理解,搜了个ACM题,试着实现,如下:

变态的比赛规则
2006 年百度之星程序设计大赛初赛题目 3
为了促进各部门员工的交流,百度 (baidu) 举办了一场全公司范围内的 " 拳皇友谊赛 " ,负责组织这场比赛的是百度的超级 " 拳皇 " 迷 W.Z. W.Z 不想用传统的淘汰赛或者循环赛的方式,而是自己制定了一个比赛规则。
由于一些员工(比如同部门或者相临部门员工)平时接触的机会比较多,为了促进不同部门之间的交流, W.Z 希望员工自己组成不同组。不同组之间的每两个人都会进行一场友谊赛而同一组内的人则之间不会打任何比赛。
比如 4 个人,编号为 1--4, 如果分为两个组并且 1,2 一个组, 3 , 4 一个组,那么一共需要打四场比赛: 1 vs 3,1 vs 4,2 vs 3,2 vs 4. 而如果是 1,2,3 一组, 4 单独一组,那么一共需要打三场比赛 : 1 vs 4,2 vs 4,3 vs 4.
很快 W.Z 意识到,这样的比赛规则可能会让比赛的场数非常多。 W.Z 想知道如果有 N 个人 , 通过上面这种比赛规则,总比赛场数有可能为 K 场吗?比如 3 个人,如果只分到一组则不需要比赛,如果分到两组则需要 2 场比赛 , 如果分为三组则需要 3 场比赛。但是无论怎么分都不可能只需要 1 场比赛。
相信作为编程高手的你一定知道该怎么回答这个问题了吧? 那么现在请你帮助 W.Z 吧。
输入
每行为一组数据,包含两个数字 N, K 。 (0<N<=500, K>=0)
输出
对输入的 N,K 如果 N 个员工通过一定的分组方式可能会一共需要 K 场比赛,则输出 "YES", 否则输出 "NO", 每组数据占一行。
所有的输入输出均为标准输入输出。
例子
输入样例
2 0
2 1
3 1
3 2
输出样例
YES
YES
NO
YES

 

#coding=utf-8
#match.py 变态的比赛规则
#分析:n个人,比赛次数最少是一组0场比赛;只要超过1组则最少n-1次比赛为,1:N-1
#最多是n*(n-1)是1:1:1:1:1...,分N组,每人都赛一场
import re
#递归实现,第一组分i 个人 由 1 到 人数-(分组数-1),这样i个人与其它人都要比一场,
#则要比i * (人数 - i). 再对剩下的(人数 - i)个人安排比赛
#gc 分组数
#n 人数
#k 已比赛次数
def make_group_and_calculate_K(gc, n, k):
    if gc == 1:
        if k == K:
            return True
        else:
            return False
    for i in range(1, n-gc+1):
        if make_group_and_calculate_K(gc-1,  n-i, k+i*(n-i)):#分组数-1,人数-i
            return True
    return False

#栓查是否可安排成功
def check():
    global N
    global K
    if N < 0 or K < 0:
        return "NO"
    if K == 0 or K == N*(N-1) or K == N-1:
        return "YES"
    if K < N-1 or K > N*(N-1):
        return "NO"
    for i in range(2, N):#分数组从2到N-1
        if make_group_and_calculate_K(i, N, 0):
            return "YES"
    return "NO"
#main
l = re.findall(r'[0-9]+', input("输入N,K:"))
N = 0
K = 0
if len(l) == 2:
    N = int(l[0])
    K = int(l[1])
    print(check())
else:
    print("输入不合法!")


PS:这段程序,貌似效率不够好,当N到40后,基本就求出解来了,现还没想到什么好方法。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值