最大子列和问题,,数组循环左移,,数列求和-加强版 pta题目解决


这里咱们进行pta部分有嗲表型题目进行讲解与展示

最大子列和问题

***题目***给定K个整数组成的序列{n1,n2,n3,nk},其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。
问题现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。
注意各组测试数据特点如下:
数据1:与样例等价,测试基本正确性;
数据2:102个随机整数;
数据3:103个随机整数;
数据4:104个随机整数;
数据5:105个随机整数;
输入格式: 输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式: 在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
结尾无空行
输出样例:
20
结尾无空行
代码一:

#include<iostream>
#include<vector>
#include<numeric>
using namespace std;
int main()
{
    vector<int>v;
    int n;
    cin>>n;
    int a,b,flag=0;b=n;
    while(b--)
        {
            cin>>a;
            if(a<0)
                {flag++;}
            v.push_back(a);
        }
    if(flag==n)//判断整数为负数
        {
            cout<<"0";
        }
    vector<int>::iterator it=v.begin();
    vector<int>::iterator its=v.end();
    a=accumulate(v.begin(), v.end(), 0);
    for(;it!=v.end();it++)//一一进行判断,比对,把所有情况均写出来然后一一比较,这里好处是不用思考即可得出答案
        {
            its=v.end();
            for(;it<=its;its--)
            {
                if(a<accumulate(it, its, 0))//采用STL中的函数,非常简便。
                    {
                        a=accumulate(it, its, 0);}
            }
        }
    cout<<a;
}

此处采用暴力枚举,并且大致类似,即将所有情况全部列举出来,然后比对,运行时间较长,可能会在测试数据时出现运行超时的情况。在数目较小时可以运行,一旦树木较大,就不行
在数目较小时可以运行,一旦树木较大,就不行
这里我又找到了另一种方法:
先上代码:

#include <iostream>
using namespace std;
int main() {
	int N, c, t = 0, maxn = 0;
	cin >> N;
	while (N--) {
		cin >> c;
		t += c;
		if (t <= 0)
			t = 0;
		maxn = max(maxn, t);
	}
	cout << maxn;
	return 0;
}

注意使用N进行计数,然后用maxn记录目前的最大结果,(由于此题目的特殊性,求顺序子列)用t来记录加上负数的情况,简直不要太妙,采用max函数进行比较,即简单又方便。而且运行时间较短,非常妙。

数组循环左移

本题要求实现一个对数组进行循环左移的简单函数:一个数组a中存有n(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移m(≥0)个位置,还需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:
输入第1行给出正整数n(≤100)和整数m(≥0);第2行给出n个整数,其间以空格分隔。
输出格式:
在一行中输出循环左移m位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
8 3
1 2 3 4 5 6 7 8
结尾无空行
输出样例:
4 5 6 7 8 1 2 3
结尾无空行

#include<iostream>
#include<list>
using namespace std;
struct lnode{
    int a;
    struct lnode *next;
};
typedef struct lnode lnode;
int main()
{
    lnode *p,*q,*l=new lnode;
    l->next=NULL;
    p=l;
    int n,m;
    int i;
    cin>>n>>m;
    while(n--)
        {
            cin>>i;
            p->a=i;q=p;
            p->next=new lnode;
            p=p->next;
        }
    delete p;
    q->next=l;
    
    while((--m)&&m>0)//注意此题目中的m的范围,否则很可能就失败。
        {
            l=l->next;
        }
    q=l;
    l=l->next;
    while(q!=l)
        {
            cout<<(l->a)<<" ";
            l=l->next;
        }
   cout<<(l->a);
}

此题注意m范围,其他都还好,此处使用循环链表,较为简单,如果使用数组,比较复杂,且移动数据较多。但是注意使用时出现的逻辑关系,否则很容易出现错误,数组越界等情况。

数列求和-加强版

题目给定某数字A(1≤A≤9)以及非负整数N(0≤N≤100000),求数列之和S=A+AA+AAA+⋯+AA⋯A(N个A)。例如A=1, N=3时,S=1+11+111=123。
&输入格式
输入数字A与非负整数N。
输出格式
输出其N项数列之和S的值。
输入样例
1 3
结尾无空行
输出样例
123
结尾无空行
第一次求解:

#include<iostream>
#include<string>
using namespace std;
int main()
{
    double n;double c,d;
    cin>>c>>n;d=c;//使用d来保存原始的c ,反之之后改变c时改变原始值
    long double sum=0;
    while(n--)
        {  
            sum+=c;
            c=c*10+d;//注意此时的c已经发生改变,如何生成多个数已经成为问题
        }
    cout<<sum;
}

但是并未充分考虑到数据的大小,使得当数据足够大时无法进行运算。
所以采用数组进行存储
第二次:

#include <stdio.h>
#define MAX_N 100000
/*  A的位数最大可能为10万,故涉及大整数,
 此题考虑用字符数组存储大整数各位
 */
int main(void){
    int A, N, i, tempSum, remainder=0;
    int arr[MAX_N+1];
    scanf("%d%d", &A, &N);
    if(N==0){
        printf("0");
        return 0;
    }
    for(i=0; i<N; i++){ /*所有加数中权值相同的位求和,低位向高位进位*/
        tempSum = A*(N-i)+remainder;
        arr[i] = tempSum%10;
        remainder = tempSum/10;
    }//从最低位算起
    if(remainder)
        arr[i] = remainder;
    else
        i--;
    for(;i>=0; i--){
        printf("%d", arr[i]);
    }
    
    return 0;
}

**注意:**这里的reminder是用来控制位数以及进位,必要时要使用
在进行这种运算时必须要记得使用数组进行运算

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值