题解:P5863 [SEERC2018] Numbers
搜索冲过去也是奇异搞笑了。
首先枚举
不会证明复杂度,但是单点最慢
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using arr = array<i64, 5>;
constexpr int maxn = 20;
i64 p[maxn];
i64 len(i64 n)
{
for (int i=1;i<=18;++i) if (n < p[i]) return i;
return 19;
}
bool chk(i64 n, int m)
{
string s = to_string(n);
if (m < s.size()) return 0;
while (s.size() < m) s = "0" + s;
string t = s;
reverse(t.begin(), t.end());
return s == t;
}
map<arr, i64> mp;
i64 f(i64 n, int x, int a, int y, int b)
{
i64 m = len(n);
if (!n) return a && b;
if (x < m - 1 && y < m - 1) return 0;
if ((!x || !y))
{
if (chk(n, x | y)) return 1;
return 0;
}
if (mp.count(arr {n, x, a, y, b})) return mp[arr {n, x, a, y, b}];
i64& ans = mp[arr {n, x, a, y, b}];
for (int i=a?0:1;i<10;++i)
for (int j=b?0:1;j<10;++j)
if ((i + j) % 10 == n % 10)
{
i64 m = n - i - j;
if (x > 1) m -= i * p[x - 1];
if (y > 1) m -= j * p[y - 1];
if (m < 0) continue;
ans += f(m / 10, max(0, x - 2), 1, max(y - 2, 0), 1);
}
return ans;
}
void solve()
{
i64 n;
cin >> n;
int m = len(n);
i64 ans = 0;
for (int i=1;i<=m;++i)
for (int j=1;j<=m;++j) ans += f(n, i, 0, j, 0);
cout << ans << '\n';
}
int main()
{
p[0] = 1;
for (int i=1;i<=18;++i) p[i] = p[i - 1] * 10;
ios::sync_with_stdio(0);
cin.tie(0);
solve();
return 0;
}