SPOJ
鏈接:
https://vjudge.net/problem/SPOJ-BALNUM
題意:
Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if:
Every even digit appears an odd number of times in its decimal representation
Every odd digit appears an even number of times in its decimal representation
For example, 77, 211, 6222 and 112334445555677 are balanced numbers while 351, 21, and 662 are not.
Given an interval [A, B], your task is to find the amount of balanced numbers in [A, B] where both A and B are included.
思路:
三進(jìn)制記錄每個(gè)值用的奇數(shù)次還是偶數(shù)次。
直接DP即可。
代碼:
// #include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<string.h>
#include<set>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int MOD = 1e9+7;
const int MAXN = 1e6+10;
ULL a, b;
ULL F[21][60000];
int dig[21];
ULL m[11];
int Upd(int x, int p)
{
int sum = 0;
for (int i = 0;i < 10;i++)
{
int tmp = x%3;
x /= 3;
if (i == p)
sum += (tmp == 1 ? 2 : 1) * m[i];
else
sum += tmp * m[i];
}
return sum;
}
bool Check(int x)
{
int p = 0;
while(x)
{
if (x%3 == 2 && p%2 == 0)
return false;
if (x%3 == 1 && p%2 == 1)
return false;
x /= 3;
p++;
}
return true;
}
ULL Dfs(int pos, int sta, bool zer, bool lim)
{
if (pos == -1)
return Check(sta);
if (!lim && F[pos][sta] != -1)
return F[pos][sta];
int up = lim ? dig[pos] : 9;
ULL ans = 0;
for (int i = 0;i <= up;i++)
{
ans += Dfs(pos-1, (zer && i == 0) ? 0 : Upd(sta, i), zer && i == 0, lim && i == up);
}
if (!lim)
F[pos][sta] = ans;
return ans;
}
ULL Solve(ULL x)
{
int p = 0;
while(x)
{
dig[p++] = x%10;
x /= 10;
}
return Dfs(p-1, 0, 1, 1);
}
int main()
{
// freopen("test.in", "r", stdin);
m[0] = 1;
for (int i = 1;i < 11;i++)
m[i] = m[i-1]*3;
memset(F, -1, sizeof(F));
int t;
scanf("%d", &t);
while(t--)
{
scanf("%llu %llu", &a, &b);
printf("%llu
", Solve(b)-Solve(a-1));
}
return 0;
}
總結(jié)
- 上一篇: 自己做的水煮鱼为什么有土腥味儿?
- 下一篇: 乡村警察老汤见义勇为被调查是哪一集