2022华东交通大学计算思维与程序设计[数位DP]标程

Question A.Fast Bit Calculations

#include <iostream>
#include <cstring>
long long int f[40][2][40];  //f[i][j][0]表示当前枚举到了第i位且前一位为j,并且这个数目前含几个连续11
long long int len; //数的长度
long long int bit[40];  //存储每一位
using namespace std;
long long int dfs(int pos, int last, int have, bool limit)  //have目前含几个连续11
{
	if (pos < 0)
		return have;
	if (!limit && ~f[pos][last][have])
		return f[pos][last][have];
	int x = limit ? bit[pos] : 1;
	long long int res = 0;
	for (int i = 0; i <= x; i++)
	{
		long long int newh = have;
		if (last == 1 && i == 1)
			newh++;
		res += dfs(pos - 1, i, newh, limit && i == x);
	}
	return limit ? res : f[pos][last][have] = res;
}
long long int get(long long int n)
{
	len = 0;
	while (n)
	{
		bit[len++] = n % 2;
		n /= 2;
	}
	return dfs(len - 1, 0, 0, 1);  //最后一个是limit
}
int main()
{
	int n, t;
	cin >> t;
	for (int i = 1; i <= t; i++)
	{
		memset(f, -1, sizeof f);
		cin >> n;
		cout << "Case " << i << ": " << get(n) << endl;
	}
	return 0;
}

Question B.Round Numbers

#include <iostream>
#include <cstring>
long long int f[100][100][100];  //f[当前位][目前有多少个0][目前有多少个1]
int len, bit[100];
using namespace std;
long long int dfs(int loc, int zero, int one, bool limit, bool first) //first:当前是不是首位
{
	if (loc < 0)
		return (zero >= one);
	if (!limit && ~f[loc][zero][one])
		return f[loc][zero][one];
	int x = limit ? bit[loc] : 1;
	long long int ans = 0;
	for (int i = 0; i <= x; i++)
	{
		if (first == 1)
		{
			if (i == 0)  //首位且第一位是0
				ans += dfs(loc - 1, 0, 0, limit && i == x, 1);
			else if (i == 1)
				ans += dfs(loc - 1, zero, one + 1, limit && i == x, 0);
		}
		else if (first == 0)
		{
			if (i == 0)
				ans += dfs(loc - 1, zero + 1, one, limit && i == x, 0);
			else if (i == 1)
				ans += dfs(loc - 1, zero, one + 1, limit && i == x, 0);
		}
	}
	return limit ? ans : f[loc][zero][one] = ans;
}
long long int get(long long int n)
{
	int len = 0;
	while (n)
	{
		bit[len++] = n % 2;
		n /= 2;
	}
	return dfs(len - 1, 0, 0, 1, 1);
}
int main()
{
	memset(f, -1, sizeof f);
	long long int l, r;
	cin >> l >> r;
	cout << get(r) - get(l - 1);
	return 0;
}

Question C.How Many Zeroes?

#include <iostream>
#include <cstring>
long long int f[100][100];  //f[当前位][目前有多少个0]
int len, bit[100];
using namespace std;
long long int dfs(int loc, int zero, bool limit, bool first) //first:当前是不是首位
{
	if (loc < 0)
		return first ? 1 : zero;
	if (!first && !limit && ~f[loc][zero])
		return f[loc][zero];
	int x = limit ? bit[loc] : 9;
	long long int ans = 0;
	for (int i = 0; i <= x; i++)
	{
		if (first == 1 && i == 0)
			ans += dfs(loc - 1, 0, limit && x == i, 1);
		else if (i == 0)
			ans += dfs(loc - 1, zero + 1, limit && x == i, 0);
		else
			ans += dfs(loc - 1, zero, limit && x == i, 0);
	}
	if (!first && !limit)
		f[loc][zero] = ans;
	return ans;
}
long long int get(long long int n)
{
	int len = 0;
	if (n == 0)
		return 1;
	while (n)
	{
		bit[len++] = n % 10;
		n /= 10;
	}
	return dfs(len - 1, 0, 1, 1);
}
int main()
{
	long long int l, r;
	int t;
	cin >> t;
	for (int i = 1; i <= t; i++)
	{
		memset(f, -1, sizeof f);
		cin >> l >> r;
		cout << "Case " << i << ": ";
		cout << get(r) - get(l - 1) << endl;
	}
	return 0;
}

Question D.Beautiful numbers

#include <cstring>
#include <iostream>  
#include <algorithm>
int t[2525], cnt;
long long f[20][50][2520];
int len, bit[20];
using namespace std;
int gcd(int a, int b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
int lcm(int a, int b)
{
    int c = gcd(a, b);
    return a * b / c;
}
long long dfs(int pos, int last, int mod, bool limit)
{
    if (pos < 0)
        return !(mod % last);
    if (!limit && f[pos][t[last]][mod] != -1)
        return f[pos][t[last]][mod];
        int x = limit ? bit[pos] : 9;
        long long res = 0;
        for (int i = 0; i <= x; i++)
        {
            int newlast = last;
            if (i)
                newlast = lcm(last, i);
            res += dfs(pos - 1, newlast, (mod * 10 + i) % 2520, limit && i == x);
        }
    return limit ? res : f[pos][t[last]][mod] = res;
}
long long get(long long n)
{
    len = 0;
    while (n)
    {
        bit[len++] = n % 10;
        n /= 10;
    }
    return dfs(len - 1, 1, 0, 1);
}
int main()
{
    memset(f, -1, sizeof f);
    for (int i = 1; i <= 2520; i++)
        if (2520 % i == 0)
            t[i] = ++cnt;
    int t;
    cin >> t;
    while (t--)
    {
        long long l, r;
        cin >> l >> r;
        cout << get(r) - get(l - 1) << endl;
    }
    return 0;
}

Question E.不要62

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int f[10][2];
int len, bit[10];
int dfs(int pos, bool last, bool limit) 
{
	if (pos < 0)	
		return 1;
	if (!limit && ~f[pos][last])	
		return f[pos][last];
	int x = limit ? bit[pos] : 9;
	int res = 0;
	for (int i = 0; i <= x; i++)
	{
		if (i == 4 || last && i == 2)	
			continue;
		res += dfs(pos - 1, i == 6, limit && i == x);
	}
	if (!limit)
		f[pos][last] = res;
	return res;
}
int get(int n)
{
	bit[0] = 0;
	len = 0;
	while (n)	
		bit[len++] = n % 10, n /= 10;
	return dfs(len - 1, 0, 1);
}
int main()
{
	memset(f, -1, sizeof f);
	int l, r;
	while (cin >> l >> r, l)
		cout << get(r) - get(l - 1) << endl;
	return 0;
}

Question F.Bomb

#include <iostream>
#include <cstring>
using namespace std;
long long f[40][20][40];  //这一位的位置,上一位是啥,现在有多少49
int len, bit[40];
long long dfs(int pos, int last, int how, bool limit)
{
	if (pos < 0)
		return (how > 0);
	if (!limit && ~f[pos][last][how])
		return f[pos][last][how];
	int x = limit ? bit[pos] : 9;
	long long ans = 0;
	for (int i = 0; i <= x; i++)
	{
		if (i == 9 && last == 4)
			ans += dfs(pos - 1, i, how + 1, limit && i == x);
		else
			ans += dfs(pos - 1, i, how, limit && i == x);
	}
	return limit ? ans : f[pos][last][how] = ans;
}
long long get(long long n)
{
	len = 0;
	while (n)
	{
		bit[len++] = n % 10;
		n /= 10;
	}
	return dfs(len - 1, 0, 0, 1);
}
int main()
{
	int t;
	long long n;
	cin >> t;
	while (t--)
	{
		cin >> n;
		memset(f, -1, sizeof f);
		cout << get(n) << endl;
	}
	return 0;
}

Question G.吉哥系列故事——恨7不成妻

#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
ll l, r;
struct Node
{
    ll num, sum, sqsum;
}dp[20][10][10];
int d[20], len, t;
ll p[20];
const ll mod = 1e9 + 7;
Node dfs(int v, int sum, int num, bool flag)
{
    if (v <= 0)
    {
        Node tmp;
        tmp.num = (num != 0 && sum != 0);
        tmp.sum = 0;
        tmp.sqsum = 0;
        return tmp;
    }
    if (!flag && dp[v][sum][num].num != -1)
        return dp[v][sum][num];
    int up = flag ? d[v] : 9;
    Node ans;
    ans.num = ans.sum = ans.sqsum = 0;
    for (int i = 0; i <= up; i++)
    {
        if (i == 7) continue;
        Node tmp = dfs(v - 1, (sum + i) % 7, (num * 10 + i) % 7, flag && (i == up));
        ans.num += tmp.num;
        ans.num %= mod;
        ll newU = p[v - 1] * i % mod;
        ans.sum += (tmp.sum + newU * tmp.num % mod) % mod;
        ans.sum %= mod;
        ans.sqsum += ((tmp.sqsum + 2 * newU * tmp.sum % mod) % mod + tmp.num * newU % mod * newU % mod) % mod;
        ans.sqsum %= mod;
    }
    if (!flag)
        dp[v][sum][num] = ans;
    return ans;
}
ll get(ll num)
{
    len = 0;
    while (num)
    {
        d[++len] = num % 10;
        num /= 10;
    }
    return dfs(len, 0, 0, 1).sqsum;
}
int main()
{
    memset(dp, -1, sizeof(dp));
    p[0] = 1;
    for (int i = 1; i < 20; i++)
    {
        p[i] = (p[i - 1] * 10) % mod;
    }
    cin >> t;
    while (t--)
    {
        scanf("%lld %lld", &l, &r);
        printf("%lld\n", (get(r) - get(l - 1) + mod) % mod);
    }
    return 0;
}

Question H.B-number

#include <iostream>
#include <cstring>
int f[10][10][13][2];
int len, bit[10];
using namespace std;
int dfs(int pos, int last, int mod, bool flag, bool limit)
{
	if (pos < 0)
		return !mod && flag;
	if (!limit && ~f[pos][last][mod][flag])
		return f[pos][last][mod][flag];
	int x = limit ? bit[pos] : 9; int res = 0;
	for (int i = 0; i <= x; i++)
	{
		bool newf = flag;
		if (last == 1 && i == 3)
			newf = 1;
		res += dfs(pos - 1, i, (mod * 10 + i) % 13, newf, limit && i == x);
	}
	return limit ? res : f[pos][last][mod][flag] = res;
}
int get(int n)
{
	len = 0;
	while (n)
	{
		bit[len++] = n % 10;
		n /= 10;
	}
	return dfs(len - 1, 0, 0, 0, 1);
}
int main()
{
	memset(f, -1, sizeof f);
	int n;
	while (cin >> n)
		cout << get(n) << endl;
	return 0;
}

 如有疏漏之处请指出,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值