标签:数位dp
问题描述
In the New Year 2014, Xiao Ming is thinking about the question: give two integers N and K, Calculate the number of the numbers of satisfy the following conditions:
It is a positive integer and is not greater than N.
Xor value of its all digital is K.
For example N = 12, K = 3, the number of satisfy condition is 3 and 12 (3 = 3, 1 ^ 2 = 3).
In order to let Xiao Ming happy in the New Year 2014, can you help him?
输入
There are multiple test cases, each test sample contains two positive integers N and K (0 <= N, K < 10 ^ 18), End to file.
输出
For each case, output the number of the numbers of satisfy condition in one line.
样例输入
12 3
999 5
12354 8
样例输出
2
76
662
提示
无
来源
宁静致远 @HBMY
操作
曾几何时,这道题根本不会,最近oj修好了,偶然看到这道题,就来弥补一下缺憾
很水的数位dp 显然个位数异或顶多到15
/*************************************************************************
> File Name: NOJ1545.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年04月14日 星期二 15时21分34秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
LL dp[30][30];
int bit[30];
LL dfs(int cur, int _xor, bool flag, bool zero)
{
if (cur == -1)
{
if (zero)
{
return 0;
}
return _xor == 0;
}
if (!flag && ~dp[cur][_xor])
{
return dp[cur][_xor];
}
LL ans = 0;
int end = flag ? bit[cur] : 9;
for (int i = 0; i <= end; ++i)
{
if (zero && !i)
{
ans += dfs(cur - 1, _xor, flag && (i == end), 1);
}
else
{
ans += dfs(cur - 1, _xor ^ i, flag && (i == end), 0);
}
}
if (!flag)
{
dp[cur][_xor] = ans;
}
return ans;
}
LL calc(LL n, LL k)
{
int cnt = 0;
while (n)
{
bit[cnt++] = n % 10;
n /= 10;
}
return dfs(cnt - 1, k, 1, 1);
}
int main()
{
memset(dp, -1, sizeof(dp));
LL n, k;
while (cin >> n >> k)
{
if (k > 15)
{
cout << 0 << endl;
continue;
}
int low = 0;
if (k == 0)
{
++low;
}
cout << calc(n, k) - low << endl;
}
return 0;
}
标签:数位dp
原文地址:http://blog.csdn.net/guard_mine/article/details/45043105