2-06. 数列求和

给定某数字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
1 3
123
2
6 100
7407407407407407407407407407407407407407407407407407407407407407407407407407407407407407407407407340
3
1 0
0

做法一

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

void init(int *temp, int *ans, int A, int N)
{
    int i = 0;
    for (i = 0; i < N; i++)
    {
        temp[i] = A;
        ans[i] = 0;
    }
    ans[i] = 0;

    return;
}
void display(int *p, int N)
{
    int i = 0;
    for (i = 0; i < N; i++)
    {
        printf("%d ", p[i]);
    }
    printf("\n");
    return;
}
void display2(int *p, int N)
{
    int i = 0;
    while (p[N] == 0)
    {
        N--;
    }
    for (i = N; i >= 0; i--)
    {
        printf("%d", p[i]);
    }
    printf("\n");
    return;
}
int *solver(int *temp, int *ans, int N)
{
    int c = 0; //进位
    int t = 0; //临时变量
    int i = 0, j = 0;
    for (i = 0; i < N; i++)
    {
        c = 0;
        for (j = 0; j <= i; j++)
        {
            t = temp[j]+ans[j]+c;
            c = t/10;
            ans[j] = t%10;
        }
        ans[j] = c;
//        display2(ans, j);
    }
    return ans;
}
int main()
{
    int A = 0, N = 0;
    int *temp = NULL;
    int *ans = NULL;
    scanf("%d%d", &A, &N);
    if (N == 0)
    {
        printf("0\n");
    }else
    {
        temp = (int*)malloc(sizeof(int)*N);
        ans = (int*)malloc(sizeof(int)*(N+1));
        init(temp, ans, A, N);
        ans = solver(temp, ans, N);
        display2(ans, N);
    }
    return 0;
}

分析1:
这里利用了两个数组,其中一个是存放临时变量的,即temp存放A/AA/AAA/AAAA/.../AAAAA...AAA,ans存放加法得到的临时结果,即每加一个数更新一次。
这里逻辑上很好理解,但是时间复杂度是T(N^2),对于小于等于10000的数来说,速度还是可以接受,但是如果是10^5,甚至更大的数的时候,运行时间就略长了,也就不符合要求了。

做法二

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

void display2(int *p, int N)
{
    int i = 0;
    while (p[N] == 0)
    {
        N--;
    }
    for (i = N; i >= 0; i--)
    {
        printf("%d", p[i]);
    }

    printf("\n");
    return;
}
int *solver(int *ans, int A, int N)
{
    int t = 0; //аый╠╠Да©
    int i = 0;
    for (i = 0; i < N; i++)
    {
        t = t + A*(N-i);
        ans[i] = t%10;
        t = t/10;
    }
    ans[i] = t;
    return ans;
}
int main()
{
    int A = 0, N = 0;
    int *ans = NULL;
    scanf("%d%d", &A, &N);
    if (N == 0)
    {
        printf("0\n");
    }else{
        ans = (int*)malloc(sizeof(int)*(N+1));
        ans = solver(ans, A, N);
        display2(ans, N);
    }
    return 0;
}
分析2:
这个方法的思路来源于秦九韶算法 点击打开链接,也就是对要进行计算的数字,按个位数、十位数、百位数等等进行拆分,而程序实现时,我们采用数组进行存储,省去了拆分的过程。
具体过程如下图所示

PS:这个题目调试了一个下午了,其实现在想通了也就挺简单的。



---------------------------------------------------------------我是一条分割线-----------------------------------增加时间:2015年6月24日22:17:38------------------------------------------------------------------------------------------------------------------------------------------------------------------------
今天没事儿,对这道题按照做法2,写了一个Java版本,放到PAT的OJ测试中,居然运行超时。。。

所以说,选对语言也是很重要的啊。。。
以下附上我进行测试的Java版本的测试程序
package com.Chapter2;

import java.util.Scanner;

/* 2-06 数列求和
 * 给定某数字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。
 *  结果:
 *  
 */
public class SumOfSequence_v3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		int A = input.nextInt();
		int N = input.nextInt();
		if (N == 0)
		{
			System.out.println("0");
		}else
		{
			long t1 = System.currentTimeMillis();
			int[] ans = solver(A, N);
			long t2 = System.currentTimeMillis();
			//System.out.println(t2-t1);
			display(ans);
		}
		
		input.close();
	}
	public static void display(int[] p)
	{
		int N = p.length-1;
		while (p[N] == 0)
		{
			N--;
		}
		for (int i = N; i >= 0; i--)
		{
			System.out.print(p[i]);
		}
		return;
	}
	
	public static int[] solver(int A, int N)
	{
		int[] temp = new int[N];
		for (int i = 0; i < N; i++)
		{
			temp[i] = A;
		}
		int[] ans = new int[N+1];
		int t = 0; //进位
		for (int i = 0; i < N; i++)
		{
			t = temp[i]*(N-i) + t;
			ans[i] = t%10;
			t = t/10;
		}
		ans[N] = t;
		return ans;
	}
	
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值