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;
}
分类:
算法刷题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】