问题描述
A positive integer X is called a “Neq Number” if it satisfies the following condition:
- When X is written in decimal notation, no two adjacent characters are the same.
For example, 1, 173, and 9090 are Neq Numbers, while 22 and 6335 are not.
You are given a positive integer K. Find the K-th smallest Neq Number.
You have T test cases to solve.
Constraints
1≤T≤100
1≤K≤
1
0
12
10^{12}
1012
All input values are integers.
Input
The input is given from Standard Input in the following format:
T
case 1
⋮
case T
Each case is given in the following format:
K
Output
Print T lines. The i-th line should contain the answer for the i-th test case
Code
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[20][10]; // pos|state, state即为a[pos+1]
int a[20];
ll dfs(int pos, int state, bool limit, bool lead) {
if (pos==-1)
return 1;
if (state!=-1&&dp[pos][state]!=-1&&!lead&&!limit)
return dp[pos][state];
int up=limit?a[pos]:9;
ll num=0;
for (int i=0;i<=up;i++) {
if (i==state) {
if (state==0&&lead)
num += dfs(pos-1, i, limit&i==up, lead&i==0);
else
continue;
} else
num += dfs(pos-1, i, limit&i==up, lead&i==0);
}
if (!lead&&!limit)
dp[pos][state] = num;
return num;
}
ll cal(ll x) {
int cnt=0;
while(x) {
a[cnt++]=x%10, x/=10;
}
return dfs(cnt-1, -1, true, true)-1; // 注意减1(因为它把0也算进去了)
}
ll lower_bound(ll k) {
ll left=k, right=1e18;
while (left<right) {
ll mid=left+right>>1;
if (cal(mid)>=k) {
right = mid;
} else {
left = mid+1;
}
}
return left;
}
int main() {
int t;
cin>>t;
ll k;
memset(dp,-1,sizeof(dp));
while(t--) {
cin>>k;
cout << lower_bound(k) << endl;
}
}