2-06. 数列求和

来源:互联网 发布:oracle数据库外键约束 编辑:程序博客网 时间:2024/05/28 17:05

给定某数字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 stubScanner 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
原创粉丝点击