4.22代码

博客讨论了codeforces第636场(Div.3)C题的解决方案,该题要求找到正负交替子序列的最大和。博主在实现过程中遇到超时问题,尝试了不同修正方案,包括改进read()函数,但仍然无法完全避免超时。主要思路是读取序列后,寻找连续序列中的最大值,并在正负交替时更新累计和。

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

4.22
1. codeforces #636(Div.3)C题:简单思维

题目大意:给一个序列,求最长交替子序列(先后顺序不变,正负交替)的最大和。

想法

输入的过程判断,flag记录前一个数的正负,pre记录前一个值;如果正负交替就更新sum,如果正负相同,sum-=,+=,记最大值。

出现问题:超时
修正:别人的代码;修改之后也超时,但是read()就不超时——我的代码read还是超时…
//超时代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f

using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
int vis[maxn], dp[maxn], cntt[maxn];


//超时
//read()还是超时
int main(){
    int t;
    ll n, cnt = 0;
    cin>>t;
    ll flag = 0, pre = 0;
    while(t--){
        memset(dp, 0, sizeof(dp));
        memset(vis, 0, sizeof(vis));
        memset(cntt, 0, sizeof(cntt));
        n = read();
        cnt = 0;
        ll sum = 0;
        for(int i = 1; i <= n; i++){
            vis[i] = read();
            //cout<<1<<" "<<vis[i]<<endl;
            if(i == 1){
                cnt++;
                pre= flag = vis[i];
                cntt[i] = cnt;
                sum+=vis[i];
                //cout<<2<<" "<<vis[i]<<endl;
            }
            else if(flag*vis[i] < 0){
                pre = flag = vis[i];
                cnt++;
                cntt[i] = cnt;
                sum+=vis[i];
                //cout<<3<<" "<<vis[i]<<endl;
            }
            else if(vis[i]>pre){
                    sum-=pre;
                    sum+=vis[i];
                    pre = vis[i];
                    cntt[i] = cnt;

                    //cout<<4<<" "<<vis[i]<<endl;
            }
        }
        /*
        for(int i = n; i >= 1; i--){
            if(cntt[i] == cnt){
                sum+=vis[i];
                cnt--;
            }
        }
        */

        printf("%lld\n", sum);
    }
    return 0;
}

思路:read()读入之后,依次遍历处理序列,m找到连续序列中最大值,等到正负交替(即序列交替时),sum+=m。
//AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f

using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
int vis[maxn], dp[maxn], cntt[maxn];

//read(),解决超时问题

int main(){
    int t;
    ll n, cnt = 0;
    cin>>t;
    ll flag = 0, pre = 0;
    while(t--){

        n = read();

        for(int i = 1; i <= n; i++){
            vis[i] = read();

        }
        ll sum = 0;
        int m = inf*(-1);
        flag = abs(vis[1])/vis[1];
        for(int i = 1; i <= n; i++){
            if(vis[i]*flag>0){
                m = max(m, vis[i]);
            }
            else{
                flag = abs(vis[i])/vis[i];
                sum+=m;
                //cout<<"          "<<m<<endl;
                m = vis[i];
            }
        }

        sum+=m;
        printf("%lld\n", sum);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值