https://cn.vjudge.net/contest/165541#problem/C
给定一群人(初始排名是i)的成功挑战次数。
规则是 每次和比他排名前面那个人挑战,如果赢了就互相换排名
问你是否可以确定冠军。
每个人的成功挑战次数都是一定的,他把所有的人都打败了就再也不能了,并且在这其中他也输过
这就是最大的挑战次数。
最大就是他从最后打到最后,先打最后把,就是把他排名后面的数都加上。
第一个后面是3,那就是3(顺序就是别人先赢他,他在赢别人)。
但是如果是0的话就不行了。
因为0都是赢不了别人的,所以肯定是在最后,
那么这个冠军最后肯定是 后面一排00000
但是0之后的非0数可以通过击败0来和k对战。
那么他的成功次数就要消耗一部分在0身上,这取决于他前面的0的个数
然后把 这些所有数都给加起来。就是他要赢的最大的可能性。
如果等于的话,就是别人都和他对战,但是如果别人不和他对战呢。
他可以主动找别人对战。那么他就肯定赢了
如果他比那个数还大,那么他就肯定赢不了。
1 并且要注意0是对0后面的非零数都有影响。
2 虽然题目要求是 相邻的,才能互相挑战,但是实际的过程中,某一个数前面的数可能会变,所以他不只是和初始最前面的比。。
开始卡在这里,想了好一会。。。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <string>
using namespace std;
const int maxn=1e6+4;
long long a[maxn];
long long sum[maxn];
int main()
{ ios::sync_with_stdio(false);
int m;
int t=0;
while(cin>>m)
{ t++;
sum[0]=0; //排名第一的要保持第一不需要任何操作
for(int i=1;i<=m;i++)
{cin>>a[i];
sum[i]=sum[i-1]+a[i]+1;
}
int k=0;
if(t>=40) continue;
for(int i=1;i<=m;i++)
{ if(a[i]>=sum[i-1])
k=i;
}
long long vv=0;
long long tt=0;
for(int i=k+1;i<=m;i++)
{ if(a[i]<=tt)
tt++;
else
{vv+=a[i]-tt;
}
}
if(vv+sum[k-1]==a[k])
{ cout<<k<<endl;
}
else if(vv+sum[k-1]>a[k])
cout<<"Unknown"<<endl;
else
cout<<"Bad Rescue"<<endl;
}
return 0;
}