给定某数字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;
}
}