代码源:955、算的我头都大了

184 阅读3分钟

logo.png

题目描述

这是代码源5月21日的div2每日一题

算的我头都大啦 - 题目 - Daimayuan Online Judge

爱数学的小明又回来辣!看了上次大家解决问题的方法后觉得自己实在是太笨了,同时引来了同是数学爱好者的小红的嘲笑,自尊心极强的小明气不过,便和小红打个赌,让小红出一道数学题给小明写,如果小明能在一周内写出来,小红就请他吃下个星期的疯狂星期四,如果做不出来就要小明请她疯狂星期四。

但是这道题实在是太难啦,小明把自己关在房间里想了一周也没能想出来,明天就是赌约的截止日期了,小明非常想吃KFC,于是他想到了再次向你求助,并承诺只要帮他写出这道题就把小红请的KFC分你一半。

小红设立了两个函数 f(x)和g(x,m) ,f(x)的定义如下:

屏幕截图 2022-05-23 191540.png

比如:f(2013)=(2013∗13∗13∗3)mod2014

g(x,m)的定义如下:

屏幕截图 2022-05-23 191618.png

比如g(x,2)=f(f(x))g(x,2)=f(f(x)) 现在,要你求出 ∑mi=1g(x,i)的值。

为了KFC,拼了!

输入格式

第一行有一个数T (1≤T≤20),代表一共有T组数据。 接下来T行有两个数x,m(1≤x,m≤10^ 9),代表g(x,m)的两个参数

输出格式

对于每行测试例输出一个数字。

问题解析

我们假设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;
}

\

AC代码

#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;
}