hdu4567 Brilliant Programmers Show

本文详细解析了一种挑战次数统计算法,通过向前和向后统计最大挑战次数来确定个体达到特定位置所需的最多挑战次数。文章提供了具体实例和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题好难啊~~~~攀攀好厉害啊~~~~~经过我们两天的交流终于弄明白了啊~~~~~~求赞求赞啊啊~~~~~~~~


目前好像只有这一篇解题报告,大体上写的很详细:点击打开链接

这题主要方法就是分向前和向后统计最大挑战次数,与自身挑战成功的值比较

为什么要分向前和向后来统计呢?这个小攀攀跟我解释了半天我也只是一知半解。。有问题请找小攀攀

我就解释下里面提到的,与前面和与后面相互超越 的最大次数


这个最大次数,指的是,超过前面所有人,到第一个,最多需要多少次挑战,这里先不管自身到底能挑战成功多少次

向后也一样,指最多被挑战多少次到最后


那么这个最多挑战次数怎么算呢?

举个例子,例如:编号为1,2,3,4,的4个人挑战成功的次数分别为,1,2,1,2(v[i])

取第三个人为例,

3要到2前面,最坏情况是,2的每一次挑战成功都是对3成功的,这样的话,3到2前面就要2的成功次数+1,即2+1

然后3要到1前面也一样,最多要1的成功次数加1次

然后第i位向前的总次数l[i],就是超过前面每一位需要次数的和,可以用递归来算,l[i]=l[i-1]+v[i]+1


再算向后最多次数

3要到最后,最多就是后面每一位的挑战次数都给3,累加即可,但是。。

向后会遇到一个问题,取第i个为例

如果后面有0的话,0是不可能超过前面任何一个的,0后面的非零值可以挑战到0的前面,再跟i挑战,那么i向后至多只能到所有0的前面

//所以0后面的非零值需要-1,再累加,但是。。这是针对一个0后面的,第二个、第三个0后面,就需要-2、-3。。。以此类推,所以要统计0的个数b

以上的0指的是相对b是0。。就是说 比如已经出现了2个0  后面又出现一个1 这个1不可能超越这两个0 只能超过1个0 这样的话 这个1也就等效是0了

具体的看代码。。。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;

__int64 l[1000005],v[1000005],r;

int main()
{
    __int64 n,i,j,k,b;
    int t=0;
    while(~scanf("%I64d",&n))
    {
        t++;
        if(t>=40) continue;//题目测试数据的bug 看discuss就知道了
        memset(l,0,sizeof l);
        for(i=1;i<=n;i++)
        {
            scanf("%I64d",&v[i]);
            l[i]=l[i-1]+v[i]+1;
            if(l[i-1]<=v[i]) k=i;
        }
        for(i=k+1,r=0,b=0;i<=n;i++)
        {
            b+=(v[i]<=b);
            r+=max(0ll,v[i]-b);
        }
        if((r+l[k-1])==v[k]) printf("%I64d\n",k);
        else if((r+l[k-1])>v[k]) printf("Unknown\n");
        else printf("Bad Rescue\n");
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值