CF10C Digital Root

原题链接

  • 题意:给出 \(1 <= n <= 100000\) 的大小的数,然后要求 \(a \times b \neq c\) 并且 \(d(d(a) \times d(b) ) = d(c)\) ,d函数是数根的意思。
  • 题解:确实不懂数根的知识。数根有些性质,即 \(a \times b = c\) 成立,那么 \(d(d(a) \times d(b) ) = d(c)\) 也一定成立,反之则并不一定。可以发现数根只取到0-9,所以我们可以记录下来从1-n所有数,他数根值为 \(i\) 的数量,记为 \(cnt_i\) 然后即可遍历0-9三层for循环找到所有满足 \(d(d(a) \times d(b) ) = d(c)\) 的方案数,然后就是要减掉 \(a \times b \neq c\) 的方案就是答案,并且在1-n中求 \(a \times b = c\) 的方案数,就是 \(\sum_{i=1}^{n} \left \lfloor \frac{n}{i} \right\rfloor\),所以就是用第一次的值减第二次的值即可。
  • 代码:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>

using namespace std;
typedef long long ll;
const int N = 19;
const double eps = 1e-8;
struct node {
    double x, y;
}a[N];
int dp[1 << N];

int s(int x) {
    int ret = 0;
    while (x) {
        ret += x % 10;
        x /= 10;
    }
    return ret;
}
int d(int x) {
    if (s(x) <= 9)return s(x);
    else return d(s(x));
}
int cnt[110];
void solve() {
    ll sub = 0;
    int n;cin >> n;
    for (int i = 1; i <= n; i++) {
        cnt[d(i)] ++;
        sub += n/i;
    }
    ll sum = 0;
    for (int i = 0; i <= 9; i ++) {
        for (int j = 0; j <= 9; j++) {
            for (int k = 0; k <= 9; k++) {
                if (d(i * j) == k) {
                    sum += (ll)cnt[i] * cnt[j] * cnt[k];     
                } 
            }
        }
    }
    cout << sum - sub << endl;
    
}
signed main() {
    int t = 1;//cin >> t;
    while (t--) solve();
    return 0;
}
posted @ 2021-03-16 10:48  u_yan  阅读(47)  评论(0编辑  收藏  举报