• 周五. 7月 1st, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

洛谷P2657 windy数

admin

11月 28, 2021

题目链接:https://www.luogu.com.cn/problem/P2657

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 30;

ll l, r;
ll dp[maxn][maxn];

vector<int> dig;

ll dfs(int pos, int pre, int lead, int limit){
	if(!pos) return 1;
	if(!lead && !limit && dp[pos][pre] != -1) return dp[pos][pre];
	
	int lim = limit ? dig[pos] : 9;
	ll res = 0;
	for(int i = 0 ; i <= lim ; ++i){
		if(abs(pre-i) < 2) continue;
		if(lead && i == 0) { // 依旧是前导零 
			res += dfs(pos-1, 11, 1, limit & (i==lim));
		} else{
			res += dfs(pos-1, i, 0, limit & (i == lim));
		}
	}
	
	if(!lead && !limit) dp[pos][pre] = res;
	
	return res;
}

ll solve(ll x){
	dig.clear();
	memset(dp, -1, sizeof(dp));
	
	dig.push_back(-1);
	ll tmp = x;
	while(tmp){
		dig.push_back(tmp % 10);
		tmp /= 10;
	}
	
	return dfs(dig.size()-1, 11, 1, 1);
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	l = read(), r = read();
	
	printf("%lld
", solve(r) - solve(l-1));
	
	return 0;
}

发表评论

您的电子邮箱地址不会被公开。