hdu 5787 K-wolf Number


K-wolf Number

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1026    Accepted Submission(s): 388


Problem Description
Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation of x is pairwised different.
Given (L,R,K), please count how many K-wolf numbers in range of [L,R].
 

Input
The input contains multiple test cases. There are about 10 test cases.

Each test case contains three integers L, R and K.

1LR1e18
2K5
 

Output
For each test case output a line contains an integer.
 

Sample Input
  
  
1 1 2 20 100 5
 

Sample Output
  
  
1 72
 

Author
ZSTU
 

Source
 

Recommend
wange2014
 

Statistic |  Submit |  Discuss |  Note
题意:给三个数l,r,k,问在l~r范围里面任意两个相同数字间隔>=k的有多少个。

思路:很明显示数位dp,dp思路是开到5维,第一维表示位数,后面四维分别表示前4个数,注意一个问题就是前导0,这里前导0用10表示,非前导0的0就用0表示,然后化简成一般的数位dp问题了,下面给代码。

#include <map>  
#include <set>  
#include <cmath>  
#include <queue>  
#include <vector>  
#include <cstdio>  
#include <cstring>  
#include <iostream>  
#include <algorithm>  
using namespace std;
typedef long long LL;
LL dp[20][11][11][11][11];
int num[20], k;
bool check(int x,int p1,int p2,int p3,int p4){
	if (k == 2)
		return x != p4;
	if (k == 3)
		return x != p4&&x != p3;
	if (k == 4)
		return x != p4&&x != p3&&x != p2;
	if (k == 5)
		return x != p4&&x != p3&&x != p2&&x != p1;
}
LL dfs(int pos, int p1, int p2, int p3, int p4, int limit){
	if (pos < 1)
		return 1;//因为l和r的范围是大于0的所以不需要考虑特别情况了,直接返回1就好
	if (!limit&&~dp[pos][p1][p2][p3][p4])
		return dp[pos][p1][p2][p3][p4];
	int end = limit ? num[pos] : 9;
	LL ans = 0;
	for (int i = 0; i <= end; i++){
		if (!i&&p4 == 10){//前一位是前导0那么前面的肯定都是前导0
			ans += dfs(pos - 1, 10, 10, 10, 10, limit&&i == end);
		}
		else if (check(i, p1, p2, p3, p4)){
			ans += dfs(pos - 1, p2, p3, p4, i, limit&&i == end);
		}
	}
	dp[pos][p1][p2][p3][p4] = ans;
	return ans;
}
LL solve(LL x){
	int len = 0;
	while (x){
		num[++len] = x % 10;
		x /= 10;
	}
	return dfs(len, 10, 10, 10, 10, 1);
}
int main(){
	LL l, r;
	while (~scanf("%lld%lld%d", &l, &r, &k)){
		memset(dp, -1, sizeof(dp));
		printf("%lld\n", solve(r) - solve(l - 1));
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值