【超时待解决】 PTA 群群群消息

烦人奥,用树做的仍然超时,暂时做个记录
如果看到这篇的朋友有思路麻烦大力踢我!谢谢!
思想就是建树,递归,挖到底,返回。

众所周知,YooQ是图论之神,LC是数论之神。 YooQ正在看xx群里的消息。由于群里面的消息太多了,而且参差不齐,让YooQ看的很难受。不过,YooQ在群里有一个特殊权限,每一次操作可以使连续的若干个消息的长度都增加1。但是由于YooQ要和学妹聊天没时间,所以他将这个特殊权限交给你,希望你能帮他在最少的操作次数下将这些消息的长度变成一样的。

输入格式:
第一行输入样例组数t(1<=t<=20)。 每组数据输入一个n(1<=n<=100000),代表有n条消息。 接下来一行输入n个正整数

输出格式:
在一行中输出使所有消息的长度相等的最小操作次数。

输入样例:
2
3
1 2 3
5
1 2 4 3 5
输出样例:
2
5
提示
答案可能超过int范围,请用long long

20%的数据,1<=n<=10
40%的数据,1<=n<=10^3
60%的数据,1<=n<=10^​4
100%的数据,1<=n<=10^​5
​​
超时的代码(算法目前还有点问题,如果你看到这个括号以及内容,说明还没改):

#include <string.h>
#include <math.h>
#include <stdio.h>
long long num,b[100001];

long long dig(long long max,long long left,long long right){
    //printf("max:%lld l&r:%lld %lld\n",max,left,right);
    //printf("%lld %lld\n",b[max]-left,b[max]+right);
    long long i,li=0,ll,lr,ri=0,rl,rr;
    if(left==0&&right==0){
        return 0;
    }
    else if(left==0){
        for(i=max-1;i>0;i--){
            //printf("rI:%lld\n",i);
            if(b[i]!=0&&ri==0&&b[max]+right<=b[i]&&b[i]>b[max]){
                ri=i;
                rl=b[i]-b[max]-1;
                rr=b[max]+right-b[i];
                break;
            }
        }
        //printf("r:%lld %lld %lld\n",ri,rl,rr);
        
        return max-ri+dig(ri,rr,rl);
    }
    else if(right==0){
        for(i=max-1;i>0;i--){
            //printf("lI:%lld\n",i);
            if(b[i]!=0&&li==0&&b[max]-left<=b[i]&&b[i]<b[max]){
                li=i;
                ll=b[i]-b[max]+left;
                lr=b[max]-b[i]-1;
                break;
            }
        }
        //printf("l:%lld %lld %lld\n",li,ll,lr);
        return max-li+dig(li,ll,lr);
    }
    else{
        long long r1,r2;
        for(i=max-1;i>0;i--){
            //printf("l&r I:%lld\n",i);
            if(b[i]!=0&&li==0&&b[max]-left<=b[i]&&b[i]<b[max]){
                li=i;
                ll=b[i]-b[max]+left;
                lr=b[max]-b[i]-1;
                r1=max-li+dig(li,ll,lr);
            }
            if(b[i]!=0&&ri==0&&b[max]+right>=b[i]&&b[i]>b[max]){
                ri=i;
                rl=b[i]-b[max]-1;
                rr=b[max]+right-b[i];
                r2=max-ri+dig(ri,rr,rl);
            }
            if(li&&ri){
                break;
            }
        }
        //printf("%lld %lld %lld\n",r1,r2,r1+r2);
        return r1+r2;
    }
    
    printf("l&r l:%lld %lld %lld\nr:%lld %lld %lld\n",li,ll,lr,ri,rl,rr);
}
int main(){
    long long n,i;
    scanf("%lld",&n);
    while(n--){
        long long sum=0,a,max=0;
        scanf("%lld",&num);
        for(i=1;i<=num;i++){
            scanf("%lld",&a);
            //printf("%lld\n",a);
            if(a>max){
                max=a;
            }
            b[a]=i;
        }
        //printf("max:%lld\n",max);
        printf("%d\n",dig(max,b[max]-1,num-b[max]));
    }
}

如果看到这篇的朋友有思路麻烦大力踢我!谢谢!

会用到的资料
/c++结构体排序
Student Stu[100];
bool cmp2(Student a,Student b)
{
return a.id>b.id;//按照学号降序排列
//return a.id<b.id;//按照学号升序排列
}
sort(Stu,Stu+100,cmp2);
注:比较方法也可以放在结构体中或类中定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值