大撒大撒发生飞洒范德萨发生

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

const int N = 200010;

int n, m, k;
int s[N], w[N], q[N], win[N], lose[N];

bool cmp(int a, int b)
{
	if (s[a] != s[b]) return s[a] > s[b];
	return a < b;
}

int main()
{
	cin >> n >> m >> k;
	
	for (int i = 0; i < n * 2; i ++ ) cin >> s[i];
	for (int i = 0; i < n * 2; i ++ ) cin >> w[i];
	for (int i = 0; i < n * 2; i ++ ) q[i] = i;
	
	sort(q, q + n * 2, cmp);
	
	while (m -- )
	{
		int loser = 0, winer = 0;
		for (int i = 0; i < n * 2; i += 2)
		{
			int a = q[i], b = q[i + 1];
			if (w[a] < w[b])
			{
				s[b] ++ ;
				win[winer ++ ] = b;
				lose[loser ++ ] = a;
			}
			else
			{
				s[a] ++ ;
				win[winer ++ ] = a;
				lose[loser ++ ] = b; 
			}
		}
		
		int i = 0, j = 0, t = 0;
		while (i < winer && j < loser)
			if (cmp(lose[j], win[i]))
				q[t ++ ] = lose[j ++ ];
			else
				q[t ++ ] = win[i ++ ];
		
		while (i < winer) q[t ++ ] = win[i ++ ];
		while (j < loser) q[t ++ ] = lose[j ++ ];
	}
	
	printf("%d\n", q[k - 1] + 1);
	
	return 0;
}

1 comments

  • @ 2026-2-3 21:58:32

    同学你好,我看到你提交的代码,但你没有说明具体是哪道题目,也没有描述你遇到的问题。从代码结构来看,这似乎是处理多轮比赛排名的问题,类似“瑞士轮”或“天梯赛”的赛制。

    我先帮你分析一下代码中可能存在的问题:

    1. 核心逻辑疑点

    你的代码在每一轮比赛后,将胜者数组 win 和败者数组 lose 进行了一次归并排序。这里的关键在于:

    • 归并的前提是:两个数组本身已经按照 cmp 规则有序
    • winlose 数组在填充时,只是简单地按比赛顺序添加,并没有保持有序。因此,直接归并不能保证最终 q 数组的有序性。

    2. 复杂度与数据范围

    • 你的代码中,每轮比赛后进行一次 O(n)O(n) 的归并,总共 mm 轮,总复杂度 O(mn)O(m \cdot n)
    • 如果 nnmm 都很大(例如 n=105,m=105n=10^5, m=10^5),这个复杂度会超时。你需要思考:是否有必要每轮都完全重新排序?

    3. 引导性问题

    1. 题目来源:你能告诉我这是哪道题吗?或者描述一下题目的具体要求(比如输入输出格式、数据范围)?
    2. 你的思路:你设计这个归并过程的初衷是什么?是否注意到了胜者和败者数组的内部顺序问题?
    3. 观察性质:考虑每一轮比赛后,胜者组的分数都增加了 1 分,败者组分数不变。那么,胜者组内部、败者组内部的相对顺序会发生变化吗?

    4. 改进方向

    • 如果两个数组本身有序,归并才是正确的。你可以先分别对 winlose 排序,但这样会增加复杂度。
    • 更优的思路是:利用分数只增加 1 的性质,胜者组和败者组在比赛后仍然各自保持有序。这样,你就可以用两个有序数组进行归并,达到 O(n)O(n) 每轮的效果。

    5. 建议

    请你先补充题目信息和你遇到的问题描述。如果你愿意,可以尝试回答上面的引导性问题,我会进一步帮助你理清思路。

    记住:在竞赛中,理解数据范围和题目性质是设计高效算法的第一步。

    • @ 2026-2-3 21:58:58

      请直接给我 ac 代码

  • 1