闲来无事,也好久没写这些码码。找个题目练练
/*--------------------------------------------------------
给定a和n,计算a+aa+aaa+aaaa+...+a...a(n个a) 的和。
输入描述:
测试数据有多组,以文件结尾。每行输入a,n(1<=a,n<=1000000)。
输出描述:
由于结果可能比较大,所以请输出答案mod 1000000007。
--------------------------------------------------------*/
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
// 打开文件
ifstream myfile;
myfile.open ("Sum.txt", ios::in);
if (myfile.bad()) // 是否成功打开
cout << "The File is failed to open." << endl;
unsigned a, n, temp, sum;
while (myfile >> a >> n) // 从文件中读取a, n值
{
temp = sum = a;
for (unsigned i = 1; i < n; i++)
{
temp = temp * (unsigned) pow(10, (unsigned) (log(a) / log(10) + 1)) + a;
// log对数运算求指数, pow求任意次方
sum = sum + temp;
}
cout << sum % 1000000007 << endl;
}
system("pause"); // 系统暂停
return 0;
}
结果如下:
可是题目要求 1<=a,n<=1000000,n = 10000时,这个数就有10000位,上述unsigned类型就不适合了。所有就有了下个修改版:
/*--------------------------------------------------------
给定a和n,计算a+aa+aaa+aaaa+...+a...a(n个a) 的和。
输入描述:
测试数据有多组,以文件结尾。每行输入a,n(1<=a,n<=1000000)。
输出描述:
由于结果可能比较大,所以请输出答案mod 1000000007。
--------------------------------------------------------*/
#include <iostream>
#include <fstream>
#include <cstdlib>
#define NUM 1000000
using namespace std;
int main()
{
// 打开文件
ifstream myfile;
myfile.open ("C:\\Users\\Sang\\Desktop\\SumResult\\Debug\\Sum.txt", ios::in);
if (myfile.bad()) // 是否成功打开
cout << "The File is failed to open." << endl;
int a, n;
char *ch = new char[NUM];
while (myfile >> a >> n) // 从文件中读取a, n值
{
// 取得 n个a 放入ch[NUM]
int abit = int (log(a) / log(10)) + 1; // a 的位数
n = n * abit; // 最大数的位数
for (int i = 0; i < n; i++)
ch[i] = int (a / pow(10, i % abit)) % 10 + 48;
// 取得 a 的个\十\佰...位
ch[n] = '0';
// 求和
int nsecond = n;
while (n > 1) // 一共需加 n-1 次
{
int third = 1;
for (int i = 0; i < n - third * abit; i++) // 两个数相加,需 n-1 位运算
{
ch[i] = int (a / pow(10, i % abit)) % 10
+ ch[i]; // 个\十\百...位数相加
if (ch[i] > '9') //是否需要进位
{
ch[i] = ch[i] - 10; // 个\十\百...位数加和值
int j;
for (j = i+1; j < n; j++)// 确定需要进位的最高位 + 1
if (ch[j] != '9')
break;
ch[j] = ch[j] + 1;
for (int temp = i+1; temp < j; temp++)
ch[temp] = '0'; // i+1 ~ j-1 之间需要产生进位
}
}
third++;
n--;
}
// 输出求和后的值
if (ch[nsecond] != '0')
cout << ch[nsecond];
for (int i = nsecond-1; i >= 0; i--)
cout << ch[i];
cout << endl;
}
delete ch;
system("pause"); // 系统暂停
return 0;
}
使用了char ch[1000000]个字符数组,每个字符代表一个’位‘,用字符模拟数值的加和。
结果如下:
实际上,当a=123, n = 10001时,就是10001位的数字,很考验计算机的运行速度。至于去模,暂且放弃了。