NOIP2005 循环 题解
2023-08-26 16:24:58
发布于:广东
33阅读
0回复
0点赞
算法
(高精度,数学,数论,递推)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int m;
int nums[N], power[N]; // power存的是n^L_{k-1}
// 高精度乘法
void mul(int c[], int a[], int b[])
{
static int temp[N];
memset(temp, 0, sizeof temp);
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
if (i + j < m)
temp[i + j] += a[i] * b[j];
for (int i = 0, t = 0; i < m; i++)
{
t += temp[i];
temp[i] = t % 10;
t /= 10;
}
memcpy(c, temp, sizeof temp);
}
// 高精度乘低精度
void mul(int c[], int a[], int b)
{
for (int i = 0, t = 0; i < m; i++)
{
t += a[i] * b;
c[i] = t % 10;
t /= 10;
}
}
int main()
{
string str;
cin >> str >> m;
for (int i = 0, j = str.size() - 1; j >= 0; i++, j--)
nums[i] = str[j] - '0'; // 把所有的数存入nums里
memcpy(power, nums, sizeof nums);
int per[N] = {1}; // per存周期长度
int pn[N], p1[N];// pn存n*n^iL_{k-1},p1存1*n^iL_{k-1}
for (int k = 1; k <= m; k++)
{
memcpy(pn, nums, sizeof pn); // 把 n copy到pn里
memset(p1, 0, sizeof p1); // p1初始化
p1[0] = 1;
// 求一下当前的循环节是多少
int r = 0;
while (r <= 10)
{
mul(pn, pn, power); // pn = pn * power
mul(p1, p1, power); // p1 = p1 * power
r++;
if (pn[k - 1] == nums[k - 1])
break;
}
memcpy(power, p1, sizeof p1);
if (r > 10)
{
memset(per, 0, sizeof per);
per[0] = -1;
break;
}
mul(per, per, r); // per = per * r
}
int k = m;
while (!per[k])
k--; //把前面的0去掉
while (k >= 0)
cout << per[k--]; // 从高到低把所有位输出
return 0;
}
这里空空如也
有帮助,赞一个