“深圳计算科研院杯“【F】

题意:每个人有一个耐心值,每一轮耐心值会减去当前所在位置的值,耐心值小于等于0就出队,问出队顺序

由于耐心值可以达到1e18,而人数最多只有1000人,直接模拟过程来减去数值是不可做的,肯定会T,那我们就要考虑能否直接得出每一轮出队的是谁,然后n^2去模拟出队顺序

我们可以预处理得到每一个人出队需要的轮数,然后每次去轮数最小,即最小出队轮数,之后让每个人减去位置*轮数,遇到第一个小于等于0的耐心值,之后的所有位置靠前,耐心值++

代码如下:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn = 1e4+5;
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; } ;
struct node{
    ll x;
    int pos;
}a[maxn];
int vis[maxn];
vector<int>vec;
queue<int>q;
int main()
{
    int n=read();
    rep(i,1,n) a[i].x=read(),a[i].pos=i,q.push(i);
    while(!q.empty())
    {
        ll minn=1e18+1;
        rep(i,1,n)
        {
            if(vis[i]) continue;
            ll Round;
            if(a[i].x%a[i].pos==0) Round=a[i].x/a[i].pos;
            else Round=a[i].x/a[i].pos+1;
            minn=min(minn,Round);
        }
        rep(i,1,n)
        {
            if(vis[i]) continue;
            a[i].x-=minn*a[i].pos;
        }
        rep(i,1,n)
        {
            if(vis[i]) continue;
            if(a[i].x<=0)
            {
                vec.push_back(i);
                vis[i]++;
                q.pop();
                rep(j,i+1,n)
                {
                    if(vis[j]) continue;
                    a[j].pos--;//之后的pos--
                    a[j].x++;//先出去的之后x++
                }
            }
        }
    }
    rep(i,0,n-1) printf("%d%c",vec[i],i==n-1?'\n':' ');
}
全部评论

相关推荐

喵_coding:这实习干啥了? 没写出来一点产出啊 好好回忆一下干了啥 问问ai 问问大佬 准备些话术就好了
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2025-11-25 09:53
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务