代码求hack
查看原帖
代码求hack
552298
Greenzhe楼主2023/10/30 17:39

这是我赛时写的玄学代码,当时测完大样例直接下一题了。

当时思路是:找出所有 连续的 不下降的 子序列,然后 这一段的油 全在 这一段的第一个站点 加掉。

就比如油价是 1 2 3 2 3,按照我的想法,就会把前 3 个站点的油在第 1 个站加满,后 2 个站点的油 在第 4 个站加满。按照最优想法,不是应该全在第 1 个站点加吗?

总之修修改改,缝缝补补,最后居然过了 CCF 的数据,拿了 100pts。

求 hack 或证明这种奇怪算法的正确性?

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define endl '\n'

int n;
ll d,v[100005],a[100005];
ll sum[100005];

int main(){
    freopen("road.in","r",stdin);
    freopen("road.out","w",stdout);
    scanf("%d%lld",&n,&d);
    for(int i=1;i<n;++i) scanf("%lld",&v[i]);
    for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
    for(int i=2;i<=n;++i) sum[i]=sum[i-1]+v[i-1];
    ll tot=(sum[n]+d-1)/d;
    ll ans=0,rem=0;
    for(int i=1,j=1;i<n;++i){
//        cout<<i<<' '<<sum[i]<<endl;
        while(j<n&&a[i]<=a[j]) j++;
        ll x=sum[j]-sum[i];
        if((x+d-1)/d!=(x-rem+d-1)){
            x-=rem;
            rem=0;
        }
        ans+=a[i]*((x+d-1)/d);
        rem+=(x+d-1)/d*d-x;
//        printf("%d->%d: %lld L, %lld km, rem %lld km, %lld RMB\n",i,j,(x+d-1)/d,x,rem,ans);
        i=j-1;
    }
    printf("%lld\n",ans);
    return 0;
}
2023/10/30 17:39
加载中...