AIM Tech Round 5 (rated, Div. 1 + Div. 2) E(思维,构造)

本文深入探讨了一段复杂的C++代码,该代码用于解决一项编程竞赛中的算法问题。通过对代码的逐行分析,文章详细解释了如何使用动态规划、递归和数据结构来构建解决方案。特别关注了长整型数组的处理,以及如何通过比较元素来确定最优解。此外,还讨论了在特定条件下输出特定值的策略,以确保解决方案的有效性和正确性。

#include<bits/stdc++.h>
using namespace std;
long long a[150007];
long long ans[150007];
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    int flag=0;
    for(int i=2;i<=n;i++){
        if(a[i]!=a[i-1]){//全部一样且并不全为0则无答案
            flag=1;
            break;
        }
    }
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(a[i]==0)
            cnt++;
    }
    if(cnt==n){
        printf("YES\n");
        for(int i=1;i<=n;i++)
            printf("1 ");//都是零让答案一样即可,此处选择全部输出1
        return 0;
    }
    if(!flag)
        printf("NO");
    else{
        printf("YES\n");
        long long mx=0;
        for(int i=1;i<=n;i++){
            if(a[i]>mx)
                mx=a[i];
        }
        //printf("%d\n",mx);
        if(a[1]==mx&&a[1]>a[n])
            flag=1;
        for(int i=2;i<=n;i++){
            if(a[i]==mx&&a[i]>a[i-1])
                flag=i;//找到最后一个最大值并且a[i]>a[i-1]开始递推
        }
        if(flag==n){
            ans[flag]=a[flag];
            ans[flag-1]=ans[flag]*2+a[flag-1];//不*2的情况给出一组反例例如3    0 1 0 则output1 1 1 *2后output2 1 2就避免了最大值对后面的值%时出现<=的情况
            for(int i=flag-2;i>=1;i--){
                ans[i]=ans[i+1]+a[i];//根据观察构造的函数
            }
            for(int i=1;i<=n;i++)
                printf("%lld ",ans[i]);
        }
        else if(flag!=1){//类似上一个if
            ans[flag]=a[flag];
            ans[flag-1]=ans[flag]*2+a[flag-1];
            for(int i=flag-2;i>=1;i--){
                ans[i]=ans[i+1]+a[i];
            }
            ans[n]=ans[1]+a[n];
            for(int i=n-1;i>flag;i--){
                ans[i]=ans[i+1]+a[i];
            }
            for(int i=1;i<=n;i++)
                printf("%lld ",ans[i]);
        }
        else if(flag==1){//类似上一个if
            ans[flag]=a[flag];
            ans[n]=ans[1]*2+a[n];
            for(int i=n-1;i>=2;i--){
                ans[i]=ans[i+1]+a[i];
            }
            for(int i=1;i<=n;i++)
                printf("%lld ",ans[i]);
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/ldudxy/p/10277155.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值