列表

详情


NC20669. 诡异数字

描述

有一天clccle在家里玩手机,突然手机上出现了一个诡异的黑影,眼里闪烁着白光,发出了奇怪的声音(像是正常的声音倒放之后再正放的样子),clccle努力辨别后终于听懂了这个黑影在说什么,大概如下,给定你一个区间[l,r]和多个约束,
请你求出在这个区间内满足这个约束的数字个数(不含前导零),如果clccle不能在1s内求出这个答案,就会被送入一个奇怪的旅馆(Rusty Lake Hotel),因为clccle很害怕,请你帮她在1s之内求出这个答案

输入描述

注意:此题有多组数据

第一行,一个整数T,代表数据组数

对于每组数据,

有三个数字 l,r,n

接下来n行,每行一个数字x,接下来一个数len表示数字x在数字串中连续出现的次数不能大于len

输出描述

对于每组数据

输出一个整数,表示l,r中满足约束的数字个数。(对20020219取模)

示例1

输入:

2
0  50 2
4 1
4 4
0  100 2
4 1
5 1

输出:

50
99

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 15ms, 内存消耗: 3048K, 提交时间: 2020-05-11 19:52:59

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=20020219;
int v[110],a[25];
ll dp[30][105][105],l,r;
int dfs(int pos,int pre,int num,int limit){
    if(num>v[pre]) return 0;
    if(pos==-1) return 1;
    if(!limit&&dp[pos][pre][num]!=-1) return dp[pos][pre][num];
    int up=limit?a[pos]:9;
    ll ret=0;
    for(int i=0;i<=up;i++){
        ret=(ret+dfs(pos-1,i,i==pre?num+1:1,limit&&i==a[pos]))%mod;
    }
    if(!limit) dp[pos][pre][num]=ret;
    return ret;
}
ll solve(ll x){
    int pos=0;
    while(x){
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,0,1);
}
int main(void)
{
    int t,n,x,y;
    cin>>t;
    while(t--){
        memset(v,0x3f,sizeof(v));
        memset(dp,-1,sizeof(dp));
        cin>>l>>r>>n;
        for(int i=1;i<=n;i++){
            cin>>x>>y;
            v[x]=min(v[x],y);
        }
        if(l)cout<<(solve(r)-solve(l-1)+mod)%mod<<endl;
        else cout<<solve(r)%mod<<endl;
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 16ms, 内存消耗: 612K, 提交时间: 2020-04-03 09:43:21

#include<bits/stdc++.h>
using namespace std;
long long MOD=20020219,D[25][25][25],N[25],C[25];
long long DFS(int l,int x,int s,bool f)
{
	if(!l) return 1;
	if(!f&&D[l][x][s]) return D[l][x][s];
	long long i,j=f?N[l]:9,S=0;
	for(i=0;i<=j;i++)
	{
		if(i==x&&s+1>C[x]) continue;
		if(i==x) S=(S+DFS(l-1,i,s+1,f&&i==j))%MOD;
		else S=(S+DFS(l-1,i,1,f&&i==j))%MOD; 
	}
	return f?S:D[l][x][s]=S;
}
long long F(long long n)
{
	if(n==-1) return 0;
	int i=0;
	while(n) N[++i]=n%10,n/=10;
	return DFS(i,0,0,1); 
}
int main()
{
	long long T,l,r,n,x,len;
	scanf("%lld",&T);
	while(T--)
	{
		for(n=0;n<=9;n++) C[n]=21;
		memset(D,0,sizeof(D));
		scanf("%lld%lld%lld",&l,&r,&n);
		while(n--)
		{
			scanf("%lld%lld",&x,&len);
			C[x]=min(C[x],len);
		}
		printf("%lld\n",(F(r)-F(l-1)+MOD)%MOD);
	}
	return 0;
}

上一题