“深圳计算科研院杯“【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':' ');
}
SHEIN希音公司福利 311人发布
