D题

本文探讨了一项特殊足球锦标赛的全平局预测问题,该锦标赛采用单循环赛制,每场比赛都必须决出胜负。文章提供了一个算法,用于计算在已知部分比赛结果的情况下,剩余比赛结果组合导致所有队伍进入“全平局”季后赛的可能性。

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.

题意:共有n支队伍,首先他给你m场比赛的结果,然后他让你填满其他比赛的结果,并求出所有队伍均是一半场数赢,一半场数输的情况有多少种。。。

思路:先根据他题目给的限制条件进行搜索,然后再根据每支队伍已经获得的分数进行剪枝,如果这支队伍已经赢了或输了(n-1)/2场了,那么直接跳过!

AC代码:


```cpp
/*D*/
#pragma GCC optimize(3)
#pragma comment(linker,"/STACK:102400000,1024000")
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'

int n, score[15], ans = 0;
bool vis[15][15];

void dfs(int x, int y) 
{
	if (y == 1 && (score[x - 1] > n / 2 || score[x - 2] > n / 2)) 
		return;//剪枝
	if (y != 1 && (score[x] > n / 2 || score[y - 1] > n / 2)) 
		return;//剪枝
	if (x > n) 
	{ 
		ans++; 
		return; 
	}
	if (vis[x][y]) 
	{
		if (y == x - 1) dfs(x + 1, 1);
		else dfs(x, y + 1);
		return;
	}
	score[x]++;
	if (y == x - 1) 
		dfs(x + 1, 1);
	else 
		dfs(x, y + 1);
	score[x]--;
	score[y]++;
	if (y == x - 1) 
		dfs(x + 1, 1); 
	else 
		dfs(x, y + 1);
	score[y]--;
}

signed main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	while (cin >> n && n)
	{
		int m; cin>>m;
		memset(score, 0, sizeof(score));
		memset(vis, 0, sizeof(vis));
		if (n == 9) //特判
		{
			if (m == 0) 
			{ 
				cout << 3230080 << endl;
				continue; 
			}
			if (m == 1) 
			{ 
				int x, y; cin >> x >> y;
				cout << 1615040 << endl;
				continue; 
			}
			if (m == 2) 
			{
				int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
				if (x1 == x2)
					cout << 692160 << endl;
				else
					cout << 807520 << endl;
				continue;
			}
		}
		for (int i = 1; i <= m; i++) 
		{
			int x, y; cin >> x >> y;
			vis[x][y] = vis[y][x] = 1;
			score[x]++;
		}
		ans = 0;
		dfs(2, 1);
		cout << ans << endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值