light OJ 1140 - How Many Zeroes?
题意: 给你两个数 m,n (m <= n)(超int),问你这两个数之间的所有数中零的个数。
思路:当然我们只要函数(f(x))计算0-x之间0的个数,那答案就是 f(n) - f(m-1)
如何完成这一函数呢?
1. 我们先预处理出dp[i][j] (表示以首位为j,数的长度为i的所有数的0的个数)
2. 数位处理:
给你一个数 n 如 2034 数位为4
1. 先计算数位小于4的数 (即 0 - 999)
2. 分别对其每一位进行*降位*处理
流程如下:
计算 1000 - 1999
计算 2000 - 2029
计算 2030- 2033
计算 2033
注意: 有0位时跳过这位的降位, 另还要注意这位的0对计算后面数的影响
题意:问你0----n(int)内所有数字转化成二进制数后总共有多少个11(相邻位都是1)。#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
LL dp[22][10], dd[22];
void init()
{
int i, j, k;
dd[0] = 1;
for(i = 1; i <= 21; i++)
dd[i] = dd[i-1] * 10;
dp[1][0] = 1;
for(i = 2; i <= 21; i++)
for(j = 0; j <= 9; j++)
dp[i][j] = dp[i-1][j] * 10 + dd[i-2];
//for(i = 0; i <= 10; i++)
// printf("dp[%d][%d] = %I64d\n", i, 1, dp[i][1]);
}
int a[22];
void update(LL n, int &num)
{
num = 0;
while(n) {a[num++] = n % 10; n /= 10; }
}
LL gao(LL n)
{
if(n < 0) return 0;
if(n < 10) return 1;
int num; update(n, num);
LL ans = 1, cnt = 0; // cnt表示处理到i时,给定的数n在第i位之前0的个数
int i, j, k;
//先处理数位小于num(最大数的数位)的数,如n = 1000,我们先处理 0 - 999;
for(i = 1; i < num; i++)
for(j = 1; j <= 9; j++)
ans += dp[i][j];
//分别对其每一位进行*降位*处理
for(i = num-1; i >= 0; i--)
{
if(!a[i]) {cnt++; continue; }
for(j = 1; j <= a[i]-1; j++) //处理该位为 1- a[i]-1
{
ans += dp[i+1][j]; //
ans += cnt * dd[i]; // 加上i位之前出现的0的情况
}
if(i != num-1) ans += dp[i+1][0] + cnt * dd[i]; // 处理该位为 0, 注意第一位不能是0
}
ans += cnt; // 处理n,只要加上n中的0的个数
//printf("n = %I64d ans = %I64d\n", n, ans);
return ans;
}
int main()
{
int i, j, cas;
LL n, m;
init();
scanf("%d", &cas);
for(int ca = 1; ca <= cas; ca++)
{
scanf("%lld%lld", &m, &n);
printf("Case %d: %lld\n", ca, gao(n) - gao(m-1));
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
#define mp make_pair
pii dp[10][20];
int a[20];
int dfs(int pos, int len, int pre, bool lim, bool zero) {
if(!len) return mp(!pos, 1);
if(!lim && !zero) {
if(~dp[pos][len].first) {
if(!pre) return dp[pos][len].first+dp[pos][len].second;
return dp[pos][len].first;
}
}
ll ret = 0;
int m = lim ? a[len] : 9;
for(int i = 0; i <= m; i++)
pii tp = dfs(i, len-1, i, lim&&i==m, zero&&i==0);
if(!lim && !zero)
dp[pos][len] = ret;
return ret;
}
ll gao(ll x) {
if(x < 0) return 0;
int len = 0;
while(x) {
a[++len] = x%10;
x /= 10;
}
return dfs(0, len, 0, 1, 1);
}
int main() {
int cas, ca = 1;
scanf("%d", &cas);
memset(dp, -1, sizeof(dp));
while(cas--) {
ll a, b;
scanf("%lld%lld", &a, &b);
printf("Case %d: %lld\n", ca++, gao(b) - gao(a-1));
}
return 0;
}
light OJ 1032 - Fast Bit Calculation
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
int a[33];
void gao(int n, int &num)
{
num = 0;
while(n)
{
a[num++] = n % 2;
n /= 2;
}
}
LL dp[33][2];
void init()
{
dp[1][0] = dp[1][1] = 0;
dp[2][1] = 1; dp[2][0] = 0;
for(int i = 3; i <= 31; i++)
{
dp[i][1] = dp[i-1][0] + dp[i-1][1] + (1<<(i-2));
dp[i][0] = dp[i-1][1] + dp[i-1][0];
}
}
int main()
{
int i, j, n, cas;
init();
scanf("%d", &cas);
for(int ca = 1; ca <= cas; ca++)
{
scanf("%d", &n);
int m; gao(n, m);
LL ans = 0, cnt = 0;
for(i = m-1; i >= 0; i--)
{
if(a[i])
{
ans += dp[i+1][0];
ans += cnt * (1<<i);
}
if(i+1 <= m-1 && a[i] == a[i+1] && a[i] == 1) cnt++;
}
ans += cnt;
printf("Case %d: %lld\n", ca, ans);
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
#define mp make_pair
pii dp[2][35];
int a[35];
pii dfs(int pos, int len, bool lim) {
if(!len) return mp(0, 1);
if(!lim && ~dp[pos][len].first) return dp[pos][len];
int m = lim ? a[len] : 1;
pii ret = mp(0, 0);
for(int i = 0; i <= m; i++) {
pii tp = dfs(i, len-1, lim&&i==m);
ret.first += tp.first;
ret.second += tp.second;
if(pos && i) ret.first += tp.second;
}
if(!lim) dp[pos][len] = ret;
return ret;
}
ll gao(ll x) {
if(x <= 1) return 0;
int len = 0;
while(x) {
a[++len] = x&1;
x>>=1;
}
return dfs(0, len, 1).first;
}
int main() {
int cas, ca = 1;
memset(dp, -1, sizeof(dp));
scanf("%d", &cas);
while(cas--) {
ll x;
scanf("%lld", &x);
printf("Case %d: %lld\n", ca++, gao(x));
}
return 0;
}