2022-05-23每日刷题打卡
爱数学的小明又回来辣!看了上次大家解决问题的方法后觉得自己实在是太笨了,同时引来了同是数学爱好者的小红的嘲笑,自尊心极强的小明气不过,便和小红打个赌,让小红出一道数学题给小明写,如果小明能在一周内写出来,小红就请他吃下个星期的疯狂星期四,如果做不出来就要小明请她疯狂星期四。
但是这道题实在是太难啦,小明把自己关在房间里想了一周也没能想出来,明天就是赌约的截止日期了,小明非常想吃KFC,于是他想到了再次向你求助,并承诺只要帮他写出这道题就把小红请的KFC分你一半。
小红设立了两个函数 f(x)和g(x,m) ,f(x)的定义如下:
f
(
x
)
=
∏
i
=
1
m
(
x
m
o
d
1
0
i
)
m
o
d
(
x
+
1
)
f(x)=\prod_{i=1}^{m}(x \mod 10^i)\mod(x+1)
f(x)=i=1∏m(xmod10i)mod(x+1)
比如:f(2013)=(2013∗13∗13∗3)mod2014
g(x,m)的定义如下:
g
(
x
,
m
)
{
f
(
g
(
x
,
m
−
1
)
)
,
m
>
1
f
(
x
)
,
m
=
1
g(x,m) \begin{cases} f(g(x,m-1)), &\ m\ >\ 1\\ f(x), &\ m\ =\ 1 \end{cases}
g(x,m){f(g(x,m−1)),f(x), m > 1 m = 1
比如g(x,2)=f(f(x))g(x,2)=f(f(x)) 现在,要你求出 ∑mi=1g(x,i)的值。
为了KFC,拼了!
输入格式
第一行有一个数T (1≤T≤201≤T≤20),代表一共有T组数据。 接下来T行有两个数x,m(1≤x,m≤10^ 9),代表g(x,m)的两个参数
输出格式
对于每行测试例输出一个数字。
样例输入
2
3 4
4102 642
样例输出
12
21262
问题解析
我们假设g(x,1)=x1,那么g(x,2)=f(g(x,1))=f(x1)=x2,……所以我们算g(x,m)是可以根据前面的g往前推的,然后我们是可以看出,某个x经过f运算后它也会是x,此时就可以说这个值固定了,比如所有的个位数。我们可以先进行模拟,然后判断一下如果有某个数经过f运算后不变,我们就可以停止模拟,然后我们直接算当前数*剩下要模拟的次数即可。
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n'
#define int ll
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e5 + 50;
ll f(ll x)
{
ll ans = x + 1, res = 1, num = 0, math = 1;
if (x == 0)return 0;
while (x)
{
ll nums = x % 10 * math;
math *= 10;
num += nums;
x /= 10;
res = (res * num) % ans;
}
return res;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while (t--)
{
ll n, m;
cin >> n >> m;
ll res = 0, ans = n;
for (int i = 1; i <= m; i++)
{
n = f(n);
if (ans == n)
{
res += (ans * (m - i + 1));
break;
}
res += n;
ans = n;
}
cout << res << endl;
}
return 0;
}