ZCMU - 1992: Swiss-system tournament

本文介绍了一种利用归并排序思想解决竞赛问题的方法。通过将参赛者分成胜者与败者两组,并按轮次更新分数,最终确定指定排名的选手。此方案巧妙地结合了数据结构与算法知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接

题目大意:给出 2*n 个人,每次第1个人和第2个人比赛,第3个人和第4个人比赛…进行 r 轮比赛,每轮比完赛都进行排名,求出最后第 q 名是谁。能力大的获胜,获胜的加 1分,输了的加 0分。

解题思路:归并排序思想,每轮比赛,把赢者放一组,输者放一组,这样单个数组t1/t2也是有序的,然后进行合并也能保证数组nds有序。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a)
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const int maxn=1e5*2+10;
int len;

struct node
{
    int id,score,power;
}nds[maxn],t1[maxn],t2[maxn];

int cmp(node n1,node n2)
{
    return n1.score==n2.score?n1.id<n2.id:n1.score>n2.score;
}

void mergeArr()
{
//    printf("Before Merge :\n");
    /* nds因为第一次sort过,所以接下来分别分为 胜利组t1 和 失败组t2 */
    int k1=1,k2=1;
    for(int i=1;i<=len;i+=2)
    {
        if(nds[i].power>nds[i+1].power)
            nds[i].score++,t1[k1++]=nds[i],t2[k2++]=nds[i+1];
        else
            nds[i+1].score++,t1[k1++]=nds[i+1],t2[k2++]=nds[i];
    }

//    for(int i=1;i<k1;i++)
//    {
//        printf("%d ",t1[i].id);
//    }
//    puts("");
//    for(int i=1;i<k1;i++)
//    {
//        printf("%d ",t1[i].score);
//    }
//    puts("");
//
//    for(int i=1;i<k2;i++)
//    {
//        printf("%d ",t2[i].id);
//    }
//    puts("");
//    for(int i=1;i<k2;i++)
//    {
//        printf("%d ",t2[i].score);
//    }
//    puts("");
//
//    printf("After Merge :\n");
    /* 胜利组t1 和 失败组t2 合并为nds,而且一定保证是有序的,节省了原生归并排序的mergeSort步骤 */
    int i=1,j=1,k=1;
    while(i<k1&&j<k2)
    {
        if(t1[i].score>t2[j].score)
            nds[k++]=t1[i++];
        else if(t1[i].score==t2[j].score)
            t1[i].id<t2[j].id ? nds[k++]=t1[i++] : nds[k++]=t2[j++];
        else
            nds[k++]=t2[j++];
    }

    while(i<k1)
        nds[k++]=t1[i++];
    while(j<k2)
        nds[k++]=t2[j++];

//    for(i=1;i<=len;i++)
//    {
//        printf("%d ",nds[i].id);
//    }
//    puts("");
//    for(i=1;i<=len;i++)
//    {
//        printf("%d ",nds[i].score);
//    }
//    puts("");
}

//void mergeSort(int first, int last) // TLE
//{
//    if(first<last)
//    {
//        int m=first+((last-first)>>1);
//        mergeSort(first,m);
//        mergeSort(m+1,last);
//        mergeArr(first,m,last);
//    }
//}

int main()
{
    int T; scanf("%d",&T);
    int n,r,q;
    while(T-- && ~scanf("%d%d%d",&n,&r,&q))
    {
        len=2*n;
        for(int i=1;i<=len;i++)
        {
            nds[i].id=i;
            scanf("%d",&nds[i].score);
        }
        for(int i=1;i<=len;i++) scanf("%d",&nds[i].power);

        sort(nds+1,nds+1+len,cmp);
        for(int i=1;i<=r;i++)
        {
            mergeArr();
        }
        printf("%d\n",nds[q].id);
    }

    return 0;
}
### 关于 ZCMU 1407 BMI 的题解 ZCMU 1407 是一道关于 BMI 计算的编程题目。以下是该题目的解析以及一种可能的实现方式。 #### 题目描述 给定一个人的体重 \( w \) 和身高 \( h \),计算其身体质量指数(Body Mass Index, BMI)。BMI 的定义如下: \[ \text{BMI} = \frac{\text{weight}}{\text{(height)}^2} \] 其中,重量单位为千克(kg),高度单位为米(m)。根据计算出的 BMI 值,判断并输出对应的健康状况类别[^5]。 | **BMI 范围** | **健康状况** | |-----------------------|-------------------| | 小于 18.5 | 过轻 | | 18.5 至 23.9 | 正常 | | 24 至 27 | 过重 | | 27 至 30 | 轻度肥胖 | | 30 至 35 | 中度肥胖 | | 大于等于 35 | 重度肥胖 | --- #### 解法分析 此问题的核心在于输入处理、浮点运算和条件分支逻辑。具体步骤包括: 1. 输入用户的体重和身高; 2. 使用公式计算 BMI 值; 3. 判断 BMI 所属区间,并输出对应的结果。 以下是一个 C++ 实现示例: ```cpp #include <iostream> #include <iomanip> // 控制浮点数精度 using namespace std; int main() { double weight, height; while(cin >> weight >> height){ if(weight == 0 && height == 0) break; // 结束标志 double bmi = weight / (height * height); if(bmi < 18.5){ cout << "过轻" << endl; } else if(bmi >= 18.5 && bmi <= 23.9){ cout << "正常" << endl; } else if(bmi >= 24 && bmi <= 27){ cout << "过重" << endl; } else if(bmi > 27 && bmi <= 30){ cout << "轻度肥胖" << endl; } else if(bmi > 30 && bmi <= 35){ cout << "中度肥胖" << endl; } else{ cout << "重度肥胖" << endl; } } return 0; } ``` --- #### Python 实现版本 如果更倾向于使用 Python,则可以采用以下代码实现相同功能: ```python def calculate_bmi(weight, height): return weight / (height ** 2) while True: try: weight, height = map(float, input().split()) if weight == 0 and height == 0: break bmi = calculate_bmi(weight, height) if bmi < 18.5: print("过轻") elif 18.5 <= bmi <= 23.9: print("正常") elif 24 <= bmi <= 27: print("过重") elif 27 < bmi <= 30: print("轻度肥胖") elif 30 < bmi <= 35: print("中度肥胖") else: print("重度肥胖") except EOFError: break ``` --- #### 注意事项 1. 浮点数比较时需注意精度误差,尤其是在边界条件下。 2. 如果输入数据量较大,建议优化 I/O 效率,例如在 C++ 中关闭同步流 `std::ios::sync_with_stdio(false)` 并取消缓冲区绑定 `cin.tie(NULL)`[^6]。 3. 对于多组测试数据的情况,应设计循环结构来逐一读取并处理每一组输入。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆克和他的代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值