一名苦逼的OIer,想成为ACMer

Iowa_Battleship

BZOJ1833或洛谷2602 [ZJOI2010]数字计数

BZOJ原题链接

洛谷原题链接

又是套记搜模板的时候。。
\(0\sim 9\)单独统计。
定义\(f[pos][sum]\),即枚举到第\(pos\)位,前面枚举的所有位上是当前要统计的数的个数之和为\(sum\)

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 13;
ll f[N][N];
int a[N], nw;
inline ll re()
{
	ll x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
ll dfs(int pos, int s, int lm, int zero)
{
	if (pos < 0)
		return s;
	if (!lm && !zero && f[pos][s] > -1)
		return f[pos][s];
	int i, k = lm ? a[pos] : 9;
	ll S = 0;
	for (i = 0; i <= k; i++)
		S += dfs(pos - 1, s + ((!nw && !i && !zero) || (nw && i == nw)), lm && i == a[pos], zero && !i);
	if (!lm && !zero)
		return f[pos][s] = S;
	return S;
}
ll calc(ll x)
{
	int k = 0;
	memset(f, -1, sizeof(f));
	while (x > 0)
	{
		a[k++] = x % 10;
		x /= 10;
	}
	return dfs(k - 1, 0, 1, 1);
}
int main()
{
	ll x, y;
	x = re();
	y = re();
	for (nw = 0; nw <= 9; nw++)
		printf("%lld ", calc(y) - calc(x - 1));
	return 0;
}

posted on 2018-09-29 19:48  Iowa_Battleship  阅读(125)  评论(0编辑  收藏  举报

导航