Liuser's OJ 题解救助站

CPP 刷题王 2024-09-06 10:33:57 2025-05-16 14:29:24 67

题解示例,源码放在评论区倒数第三页了。

众所周知,现在很多人的题解都是因为格式问题或没有解析打回的。

如果想要知道如何使题解变得更加优秀,可以在本帖留言 @CPP 并且附上题解链接,lz 可以提出修改建议。

如果出现 某句话结尾未使用中文标点 请自行订正。




常见问题 1: 代码段未使用 markdown 格式。

解决方案: 在代码前加上 ```cpp,然后在代码后加上 ```。

例如:

```cpp

#include <bits/stdc++.h>

```

效果:

#include <bits/stdc++.h>

如果只引用一行代码,那么只需要 ```代码``` 就行了,而且不需要换行。




常见问题 2: 变量名、数字、数学公式未使用 格式。

解决方案: 在变量名、数字、数学公式前加上 $,然后在这一些东西后加上 $,例如 $a + b$,效果

有的公式需要居中显示的话那么开头和结尾都用 $$ 就行了。




请不要进行无意义回复。

{{ vote && vote.total.up }}

共 21 条回复

CPP 刷题王

## 解题思路

等价于 $x ^ 2 + S(x) \times x = n$。

我们先拆成两个部分,一个部分是 $n \leq 10^3$ 的情况,另一部分是 $10^3 < n \leq 10^{18}$ 的情况。

对于第一种情况直接暴力即可。因为懒得考虑边界条件。

对于第二种情况,我们先发现 $x ^ 2$ 是大于等于 $0$ 的,而 $S(x) \times x$ 也是大于的等于 $0$ 的,所以要想 $x ^ 2 + S(x) \times x = n$ 成立的充要条件是 $x ^ 2 \leq n$,所以我们只需要枚举到 $\sqrt{n}$ 即可。但是 $\mathcal{O}(\sqrt{n})$ 也会超时。我们发现 $S(x)$ 远小于 $x$(当位数为 $10$ 位时 $S(x)$ 最大也就 $90$),所以直接从 $\frac{\sqrt{n}}{2}$ 开始枚举还是很浪费的。

我们定义 $x = \sqrt{n},i$ 为我们从 $x - i$ 开始枚举才能保证公式的值等于 $n$。

$$(x - i) ^ 2 + S(x - i) \times (x - i) = n$$

$$x ^ 2 - 2xi + i ^ 2 + S(x - i) \times (x - i) = n$$

$$n - 2xi + i ^ 2 + S(x - i) \times (x - i) = n$$

由于 $x - i$ 最多为 $10^9$(还取不到),因此 $S(x - i)$ 为 $90$ 左右。

$$n - 2xi + i ^ 2 + 90(x - i) = n$$

$$n - 2xi + i ^ 2 + 90x - 90i = n$$

$$i^2 - (2x + 90)i + 90x = 0$$

$$\Delta = b^2 - 4ac = 4x^2 + 360x + 8100 - 360x = 4n + 8100$$

$$\sqrt{\Delta} = 2\sqrt{n + 2025}$$

$$\therefore i_1 = \frac{-b + \sqrt{\Delta}}{2a} = \frac{2x + 90 - 2\sqrt{n + 2025}}{2} = \frac{2 \times 10^9 + 90 - 2\sqrt{10^{18} + 2025}}{2} = 44.999998987500000000000512578125 \approx 45$$

$i_2$ 很明显更小,所以可以不用计算。因此经过粗略计算后我们可以得到当 $i$ 为 $45$ 时是可能满足这个式子的,但前面说了这是粗算,会存在一定的误差,因此我们让 $i = 100$ 保险一些,如果更加谨慎的话 $45 \leq i \leq 6\times 10^7$ 都可以取,反正又不会超时。

CODE:

```cpp

inline int s(int n) {

int ans = 0;

while (n) {

    ans += n % 10;

    n /= 10;

}

return ans;

}

signed main() {

ios::sync_with_stdio(false);

ios_base::sync_with_stdio(false);

cin.tie(0), cout.tie(0);

int n;

cin >> n;

int t = sqrtl(n);

for (int i = 1; i <= 1000; i++) {

    if (i * i + i * s(i) == n) {

        cout << i;

        return 0;

    }

}

for (int i = t - /*29 ~ 6 \times 10^7 都能过*/; i * i <= n; i++) {

    if (i + s(i) == n * 1.0 / i) {

        cout << i;

        return 0;

    }

}

cout << -1;

return 0;

}

```

CPP 刷题王

请在借鉴时忽略掉 $、`、# 前面的 \,这是多余的,times 等英文单词前面的 \ 是有意义的。

\## 解题思路
等价于 \$x ^ 2 + S(x) \times x = n\$。

我们先拆成两个部分,一个部分是 \$n \leq 10^3\$ 的情况,另一部分是 \$10^3 < n \leq 10^{18}\$ 的情况。

对于第一种情况直接暴力即可。因为懒得考虑边界条件。

对于第二种情况,我们先发现 \$x ^ 2\$ 是大于等于 \$0\$ 的,而 \$S(x) \times x\$ 也是大于的等于 \$0\$ 的,所以要想 \$x ^ 2 + S(x) \times x = n\$ 成立的充要条件是 \$x ^ 2 \leq n\$,所以我们只需要枚举到 \$\sqrt{n}\$ 即可。但是 \$\mathcal{O}(\sqrt{n})\$ 也会超时。我们发现 \$S(x)\$ 远小于 \$x\$(当位数为 \$10\$ 位时 \$S(x)\$ 最大也就 \$90\$),所以直接从 \$\frac{\sqrt{n}}{2}\$ 开始枚举还是很浪费的。

我们定义 \$x = \sqrt{n},i\$ 为我们从 \$x - i\$ 开始枚举才能保证公式的值等于 \$n\$。
\$\$(x - i) ^ 2 + S(x - i) \times (x - i) = n\$\$
\$\$x ^ 2 - 2xi + i ^ 2 + S(x - i) \times (x - i) = n\$\$
\$\$n - 2xi + i ^ 2 + S(x - i) \times (x - i) = n\$\$

由于 \$x - i\$ 最多为 \$10^9\$(还取不到),因此 \$S(x - i)\$ 为 \$90\$ 左右。

\$\$n - 2xi + i ^ 2 + 90(x - i) = n\$\$
\$\$n - 2xi + i ^ 2 + 90x - 90i = n\$\$
\$\$i^2 - (2x + 90)i + 90x = 0\$\$
\$\$\Delta = b^2 - 4ac = 4x^2 + 360x + 8100 - 360x = 4n + 8100\$\$
\$\$\sqrt{\Delta} = 2\sqrt{n + 2025}\$\$
\$\$\therefore i_1 = \frac{-b + \sqrt{\Delta}}{2a} = \frac{2x + 90 - 2\sqrt{n + 2025}}{2} = \frac{2 \times 10^9 + 90 - 2\sqrt{10^{18} + 2025}}{2} = 44.999998987500000000000512578125 \approx 45\$\$

\$i_2\$ 很明显更小,所以可以不用计算。因此经过粗略计算后我们可以得到当 \$i\$ 为 \$45\$ 时是可能满足这个式子的,但前面说了这是粗算,会存在一定的误差,因此我们让 \$i = 100\$ 保险一些,如果更加谨慎的话 \$45 \leq i \leq 6\times 10^7\$ 都可以取,反正又不会超时。

CODE:
\```cpp
inline int s(int n) {
    int ans = 0;
    while (n) {
        ans += n % 10;
        n /= 10;
    }
    return ans;
}
signed main() {
    ios::sync_with_stdio(false);
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    int t = sqrtl(n);
    for (int i = 1; i <= 1000; i++) {
        if (i * i + i * s(i) == n) {
            cout << i;
            return 0;
        }
    }
    for (int i = t - /*29 ~ 6 \times 10^7 都能过*/; i * i <= n; i++) {
        if (i + s(i) == n * 1.0 / i) {
            cout << i;
            return 0;
        }
    }
    cout << -1;
    return 0;
}
\```
CPP 刷题王
CPP 刷题王
CPP 刷题王
CPP 刷题王

乘号:

hezhiqian 魔镜少女

hezhiqian 魔镜少女

hezhiqian 魔镜少女

CPP 刷题王

cppp - pcppcpp