题解:CF2132B The Secret Number

· · 题解

题意简化

有一个正整数 x,然后给这个数末尾加上 k0 得到 y 。把 x + y 的结果记为 n,给你 n,找出所有可能的 x

思路

观察题目可得,因为 k 的取值范围是 2 \leq k \leq 18,所以我们考虑枚举。

在题目中,因为y = x \times 10^k,那么 n = x + x \times 10 ^k,提取公因式。就得到了 n = (10^k + 1) \cdot x,那么我们设 d = 10 ^ k + 1,于是当 d 可以被 n 整除时,就说明我们找到了 x ,并将 n \div d 的结果放入一个数组中,再把这个数组重新排序一遍即可。

Code

思路再前面说了,所以就不加注释了

#include <bits/stdc++.h>

using namespace std;

namespace RealDream {
    typedef long long ll;
    typedef unsigned long long ull;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);

        vector<ll> pows{1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000};

        int t;
        cin >> t;
        while (t--) {
            ll n;
            cin >> n;
            vector<ll> ans;

            for (int k = 1; k <= 18; k++) {
                ll d = pows[k] + 1;
                if (d > n) break;
                if (n % d == 0) ans.push_back(n / d);
            }

            sort(ans.begin(), ans.end());
            if (ans.empty()) {
                cout << 0 << endl;
            } else {
                cout << ans.size() << endl;
                for (ull i = 0; i < ans.size(); i++) {
                    if (i > 0) cout << ' ';
                    cout << ans[i];
                }
                cout << endl;
            }
        }
        return 0;
    }
};

int main() {
    RealDream::main();
    return 0;
}