2022-05-23每日刷题打卡

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=1m(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,m1)),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;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值