标签:from get 位置 ota 示例 while tip 题解 ted
[HDU3709]Balanced Number
试题描述
输入
The input contains multiple test cases. The first line is the total number of cases T (0 < T ≤ 30). For each case, there are two integers separated by a space in a line, x and y. (0 ≤ x ≤ y ≤ 1018).
输出
For each case, print the number of balanced numbers in the range [x, y] in a line.
输入示例
2 0 9 7604 24324
输出示例
10 897
数据规模及约定
见“输入”
题解
令 f[k][i][j][s] 表示考虑数的前 i 位,最高位为 j,支点在位置 k,支点右力矩 - 左力矩 = s 的数有多少个。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define LL long long
LL read() {
LL x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
return x * f;
}
#define maxn 20
#define maxs 1800
LL f[maxn][maxn][10][maxs];
int num[maxn];
LL sum(LL x) {
if(!x) return 1;
int cnt = 0; LL tx = x;
while(x) num[++cnt] = x % 10, x /= 10;
LL ans = 0;
for(int i = cnt - 1; i; i--)
for(int k = 1; k <= i; k++)
for(int j = 1; j <= 9; j++) ans += f[k][i][j][0];
for(int i = cnt; i; i--) {
for(int k = cnt; k; k--) {
int s = 0;
for(int x = cnt; x > i; x--) s += (x - k) * num[x];
if(s < 0 || s >= maxs) continue;
for(int j = i < cnt ? 0 : 1; j < num[i]; j++) {
ans += f[k][i][j][s];
// if(!j && !s && i > 1) ans--;
}
}
}
for(int k = 1; k <= cnt; k++) {
int s = 0;
for(int x = 1; x <= cnt; x++) s += (x - k) * num[x];
if(!s){ ans++; break; }
}
ans++;
return ans;
}
int main() {
for(int j = 0; j <= 9; j++) f[1][1][j][0] = 1;
for(int k = 2; k < maxn; k++)
for(int j = 0; j <= 9; j++) f[k][1][j][(k-1)*j] = 1;
for(int k = 1; k < maxn; k++)
for(int i = 1; i < maxn - 1; i++)
for(int j = 0; j <= 9; j++)
for(int s = 0; s < maxs; s++) if(f[k][i][j][s]) {
for(int x = 0; x <= 9 && s + (k - i - 1) * x >= 0; x++)
if(s + (k - i - 1) * x < maxs) f[k][i+1][x][s+(k-i-1)*x] += f[k][i][j][s];
// printf("%d %d %d %d: %lld\n", k, i, j, s, f[k][i][j][s]);
}
int T = read();
while(T--) {
LL l = read(), r = read();
LL ans = sum(r); if(l) ans -= sum(l - 1);
printf("%lld\n", ans);
}
return 0;
}
标签:from get 位置 ota 示例 while tip 题解 ted
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6127145.html