Educational Codeforces Round 104-C Minimum Ties
题目
思路
首先我们要确定在不重复比赛的情况下一共会有
n
∗
(
n
−
1
)
/
2
n*(n-1)/2
n∗(n−1)/2场比赛。这样的话每场比赛可以贡献一胜一负或者两平。
所以我们遍历最多有多少胜场这样可以保证平局最少
同时很重要的一点总分一定要可以平均分配给每个队伍。
在满足以上条件下你可以找到总的胜利场数将它合理的分配给每个球队即可,而对于平局则当知道每个队胜场之后也可知道。
代码
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
int a[105];//存储每个球队胜场
int b[105];//储存平局数
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
int sum = n * (n - 1);
int temp = n * (n - 1) / 2;
int l1;
for (; temp >= 0; temp--) {
int loop = temp * 3 + (sum - temp * 2) * 1;//总分
if (loop % n == 0) {
l1 = loop / n;//l1是每个球队最后的分数
break;
}
}
for (int i = 1; i <= n; i++) {
if (temp == 0) {
break;
}
for (int j = 1; i <= n; j++) {
if ((l1 - 3 * j) >= 0) {
a[i] = j;//将胜场分配
} else {
break;
}
}
}
for (int i = 1; i <= n; i++) {
b[i] = l1 - a[i] * 3;//平局
}
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (a[i] != 0) {
a[i]--;//现将胜利的输出之后是平局最后是负场
printf("1 ");
continue;
} else if (b[i] != 0) {
b[i]--;//一个平局两个队都要更新
b[j]--;
printf("0 ");
continue;
} else {
printf("-1 ");
a[j]--;//这个队负势必另一个队胜
}
}
}
printf("\n");
}
}