石油大2018年第四阶段组队训练赛第二场 D

探讨了一种单场循环赛制下,如何通过编写程序计算导致所有参赛队伍进入全季后赛的剩余比赛赢/输组合模式数量的问题。该程序采用深度优先搜索策略,确保各队伍胜负次数相等。

问题 D: Playoff

时间限制: 2 Sec  内存限制: 128 MB
提交: 181  解决: 59
[提交] [状态] [讨论版] [命题人:admin]

题目描述

The Minato Mirai Football Association hosts its annual championship as a single round-robin tournament, in which each team plays a single match against all the others. Unlike many other round-robin tournaments of football, matches never result in a draw in this tournament. When the regular time match is a tie, overtime is played, and, when it is a tie again, a penalty shootout is played to decide the winner.
If two or more teams won the most number of matches in the round-robin, a playoff is conducted among them to decide the champion. However, if the number of teams is an odd number, it is possible that all the teams may have the same number of wins and losses, in which case all the teams participate in the playoff, called a "full playoff" here.
Now, some of the tournament matches have already been played and we know their results. Whether or not a full playoff will be required may depend on the results of the remaining matches. Write a program that computes the number of win/loss combination patterns of the remaining matches that lead to a full playoff.
The first datatset of the Sample Input represents the results of the first three matches in a round-robin tournament of five teams, shown in the following table. In the table, gray cells indicate the matches not played yet.

In this case, all the teams win the same number of matches with only two win/loss combination patterns of the remaining matches, which lead to a full playoff, as shown below. In the two tables, the differences are indicated in light yellow.

 

输入

The input consists of multiple datasets, each in the following format.
n
m
x1 y1 
... 
xm ym 
n is an odd integer, 3, 5, 7, or 9, indicating the number of teams participating in the tournament. m is a positive integer less than n(n−1)/2, which is the number of matches already finished. xi and yi give the result of the i-th match that has already taken place, indicating that team xi defeated team yi. Each of xi and yi is an integer 1 through n which indicates the team number. No team plays against itself, that is, for any i, xi ≠ yi. The match result of the same team pair appears at most once. That is, if i ≠ j, then (xi,yi) ≠ (xj,yj) and (xi,yi) ≠ (yj,xj) hold.

The end of the input is indicated by a line containing a zero. The number of datasets does not exceed 100.

 

输出

For each dataset, output a single line containing one integer which indicates the number of possible future win/loss patterns that a full playoff will be required.

 

样例输入

5
3
3 2
4 1
5 1
3
1
1 2
3
2
1 2
3 2
5
4
4 1
4 2
5 1
5 2
5
3
4 1
4 2
5 1
5
4
3 2
4 1
5 1
5 2
9
11
6 1
6 4
7 2
7 3
7 4
8 2
8 3
8 4
9 1
9 3
9 5
9
10
6 1
6 4
7 2
7 3
7 4
8 2
8 3
8 4
9 1
9 3
5
6
4 3
2 1
5 1
2 4
1 3
2 3
9
1
1 2
0

 

样例输出

2
1
0
0
1
0
0
16
0
1615040

大意:Minato Mirai足球协会将其年度锦标赛作为单场循环赛举办,每场比赛对阵所有其他球队。与许多其他的橄榄球循环赛不同,比赛从未在本次比赛中获得平局。当常规时间比赛是平局时,将播放加时赛,并且当再次打平时,将进行点球大战以决定胜者。
如果两支或更多球队在循环赛中赢得了最多的比赛,那么他们之间会进行一场季后赛以决定冠军。但是,如果球队的数量是一个奇数,那么所有球队都可能拥有相同数量的胜负,在这种情况下,所有球队都参加了季后赛,在这里称为“全季后赛”。
现在,一些锦标赛比赛已经开始,我们知道他们的结果。是否需要完整的季后赛可能取决于剩余比赛的结果。编写一个程序,计算导致完整季后赛的剩余比赛的赢/输组合模式的数量。

思路感觉是个搜索题
设mpp[a][b]表示a击败b,win[i]表示第i只队伍赢了几次

lose[i]表示第i只队伍输了几次
然后搜索
1.每只队伍赢得次数相等那就是(n-1)/2
2.然后搜索试试

3.每次搜索要把lose[i]>(n-1)/2和win[i]>(n-1)/2的减掉

 

代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int n,m;
int a[1000][1000];
int win[1000];
int lose[1000];
int ans;
void dfs(int x,int y)
{
    if(x == n && y == n)//判断结束
    {
        ans++;
        return;
    }

    if(y > n ) // 超限
    {
        x++;
        y = 1;
    }

    if(a[x][y]!= -1 || x==y ) // 有结果的情况
    {
        dfs(x,y+1);
    }

    else
    {
        if(win[x] < (n-1)/2 && lose[y] < (n-1)/2) // 赢
        {
            a[x][y] = 1;
            a[y][x] = 0;
            win[x]++;
            lose[y]++;
            dfs(x,y+1);
            a[x][y] = -1;
            a[y][x] = -1;
            win[x]--;
            lose[y]--;
        }
        if(lose[x] < (n-1)/2 && lose[x] < (n-1)/2) //输
        {
            a[x][y] = 0;
            a[y][x] = 1;
            win[y]++;
            lose[x]++;
            dfs(x,y+1);
            a[x][y] = -1;
            a[y][x] = -1;
            win[y]--;
            lose[x]--;
        }
    }
}

int main()
{
    int w,l;
    while(scanf("%d%d",&n,&m)!=EOF && n)
    {
        int flag = 0;ans = 0;
        memset(a,-1,sizeof(a));
        memset(win,0,sizeof(win));
        memset(lose,0,sizeof(lose));
        for(int i = 1; i <= m ;i++) 
        {
           scanf("%d%d",&w,&l);
           a[w][l] = 1;
           a[l][w] = 0;
           win[w]++;
           lose[l]++;
        }
        for(int i = 1 ;i <= n ;i++) // 在比赛前先判断一下
        {
            if(win[i] > (n-1)/2)
            {
                flag = 1;
                printf("0\n");
                break;
            }
            if(lose[i] > (n-1)/2)
            {
                flag = 1;
                printf("0\n");
                break;
            }
        }
        if(!flag)
        {
            dfs(1,1);
            printf("%d\n",ans);
        }
    }
}

 

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值