codeforces刷题(1100):1904B_div2

发布时间 2023-12-26 19:55:40作者: Tom-catlll

B、Collecting Game

跳转原题点击此:该题地址

1、题目大意

  获得一个由n位正整数组成的数组。你可以选择选择任意一个数作为你的判断值。然后任意一个 \(\le\) 它的数可以被选中加入你的分数(注意判断值不算在里面),同时该数被移除数组。你的任务是,对于该数组中的每个数,都将其作为判断值并找出其所能移除的最大数量。

2、题目解析

  当选中的判断值,任何比它小的数都能直接被移出并加入你的分数。然后再根据加上这些数依次判断比判断值大的数(可以通过排序原始数列来递增地判断比判断值高的数,一旦有数比判断值加上之前所有数都要大,那么该数和比它大的所有数就都不用判断了)。至于输出,可以使用pair来为原始数组加上序号即可。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll>pii;
const int N = 1e5+10;

#define _1 first
#define _2 second

int t;
int n;

bool cmp(pii a, pii b)
{
	return a._1 < b._1;
}

void solve()
{
	cin >> n;
	pii f[n + 1];
	ll ans[n + 1];
	for(int i = 1; i <= n ;i++)
	{
		cin >> f[i]._1;
		f[i]._2 = i;	// 加入序号
	}
	sort(f + 1, f + 1 + n, cmp);	// 递增排序
	
	ll idx = 1, tmp = 0;
	for(int i = 1; i <= n ;i++)
	{
		// 直接算比f[idx]._1小的数
		while(idx <= i)	// 注意这里存在 idx == i
		{
			tmp += f[idx]._1;
			idx++;
		}
		
		// 处理比判断值大的数
		while(idx <= n && tmp >= f[idx]._1)
		{
			tmp += f[idx]._1;
			idx++;
		}
		
		ans[f[i]._2] = max(0ll, idx - 2);	// 分别减去自身和最后多递增的
	}
	
	for(int i = 1; i <= n; i++)
	{
		cout << ans[i];
		if(i != n)
			cout << " ";
		else 
			cout << endl;
	}
}

int main()
{
	cin >> t;
	while (t--)
	{
		solve();
	}

	return 0;
}