codeforces刷题(1100):1904B_div2

B、Collecting Game

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

1、题目大意

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

2、题目解析

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

3、具体代码

#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;
}

 

posted @   Tom-catlll  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
// 数学公式
点击右上角即可分享
微信分享提示