7-6 数列求和-加强版 (10 分)

7-6 数列求和-加强版 (10 分)
给定某数字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

附:
时间限制: 200 ms
内存限制: 64 MB
代码长度限制: 16 KB

思路分析

下面说一下思路历程
首先第一种方法:逐个相加,用long long存结果。很明显这种方法不行,数字位数达到了10w+。因此联想到字符串模拟。于是有了第二种方法:大数相加。这种方法加一次的时间复杂度O(n),加n次时间复杂度就是O(n2),并且这道题时间限制改成了200ms(以往的题目一般都是400ms),说明作者另有企图,卡了大数加法的时间。
此处上方法2——大数加法实现的代码

#include <iostream>
using namespace std;

string sum(string s1,string s2)
{
    if(s1.length()<s2.length())
    {
        string temp=s1;
        s1=s2;
        s2=temp;
    }
    int i,j;
    for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
    {
        s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));   //注意细节
        if(s1[i]-'0'>=10)
        {
            s1[i]=char((s1[i]-'0')%10+'0');
            if(i) s1[i-1]++;
            else s1='1'+s1;
        }
    }
    return s1;
}

int main()
{
	int A, N, tmp = 0;
	char c;
	string s1, s2;
	cin>>A>>N;
	if(N == 0) cout<<0<<endl;
	else
	{
		for(int i = 1;i <= N;i++)
		{
			c = A + '0';
			s2 += c;
			s1 = sum(s1, s2);
		}
		cout<<s1<<endl;
	}
	return 0;
}

判题结果:
在这里插入图片描述
果不其然,最后一个数据运行超时。

也就是说,在200ms的情况并且N达到了10w(程序必须要运行10w次)的条件下,我们只能采用一个时间复杂度为O(n)的方法,也是出题人暗示我们的方法。而能满足这个时间复杂度的只有一种情况:递推。先手动模拟找一下规律,然后总结出一条递推公式。也就是当前项可以由前几项通过某种公式得到。
因此,顺着这个思路,列出一些项,找一下规律。

在这里插入图片描述

#include <iostream>
using namespace std;

int main()
{
	char a[100010];
	int flag = 0, A, N;
	cin>>A>>N;
	if(N == 0) cout<<0;
	a[N+1] = '\0';
	for(int i = N;i >= 0;i--)
	{
		a[i] = (i*A + flag)%10 + '0';
		flag = (i*A + flag)/10;
	}
	if(a[0] == '0')
	{
		for(int i = 1;i <= N;i++) cout<<a[i];
	}
	else cout<<a<<endl;
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值