原题链接https://ac.nowcoder.com/acm/contest/5675/I


题目描述

目前有n支队伍,每一对队伍共要进行图片说明场比赛,而每天可以安排一场比赛。对于每支队伍,它们将在各自需要比赛的第一天到达,并在各自比赛结束的一天离开。
例如:当有三支队伍时,假如日程为(1,2),(1,3),(2,3),那么第一支队伍要在第1天到达,第2天离开,共停留2天,第二支队伍在第1天到达,第3天离开,共停留3天,第三支队伍在第2天到达,第3天离开,共停留2天。
现在需要一张安排表,以确保每支队伍各自的停留时间尽可能少。


输入描述

第一行输入一个整数T,表示测试样例的数目;
对于每个测试样例,输入一个整数n,表示参赛的球队数目。
(注:球队编号均为1~n)。

输出描述

对于每个输入的n,输出图片说明行,分别为每场比赛参赛的球队(参赛的球队的编号特定无顺序要求)。

数据范围

图片说明


样例

  • 输入

    2
    3
    4
  • 输出

    1 2
    1 3
    2 3
    1 2
    1 3
    1 4
    2 3
    2 4
    3 4

题解思路

当n支队伍两两进行比赛,很显然是图片说明场比赛,但题目给出来,一定另有意图。
当看完题目,很容易会想到直接暴力输出,代码如下:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
                printf("%d %d\n",i,j);
    }
}

难道暑期集训会放这么没有营养的东西吗。。。。。。
仔细一想,这样暴力的算法似乎不能满足题目所说的使各队伍的停留时间尽可能短。
因为这样的算法只能满足编号越靠前的队伍停留时间越短,而越靠后的队伍停留时间越长。
一拍脑袋可以想到,我们可以使用构造的方法:
1.把n支队伍分成图片说明支队伍(标为A)图片说明支队伍(标为B);
2.让A中队伍分别与A中队伍、B中队伍比赛,再让B中队伍与B中队伍比赛;
3.尝试在代码中分为4部分解决。

在构造之后可能会有一点问题,但稍微Debug+前后编号顺序问题在本题中不是问题就可以解决。


参考代码

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=2;i<=n/2;i++)
            for(int j=1;j<i;j++)
                printf("%d %d\n",j,i);
        for(int i=n/2+1;i<n;i++)
            for(int j=1;j<=n-i;j++)
                printf("%d %d\n",j,i);
        for(int i=1;i<=n/2;i++)
            for(int j=n-i+1;j<=n;j++)
                printf("%d %d\n",j,i);
        for(int i=n/2+1;i<n;i++)
            for(int j=i+1;j<=n;j++)
                printf("%d %d\n",j,i);
    }
}