您的位置:首页 > 其它

Codeforces Beta Round #91 (Div. 2 Only)-E. Lucky Permutation

2016-08-20 19:34 627 查看
原题链接

E. Lucky Permutation

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7.
For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are
not.

One day Petya dreamt of a lexicographically k-th permutation of integers from 1 to n.
Determine how many lucky numbers in the permutation are located on the positions whose indexes are also lucky numbers.

Input

The first line contains two integers n and k (1 ≤ n, k ≤ 109) —
the number of elements in the permutation and the lexicographical number of the permutation.

Output

If the k-th permutation of numbers from 1 to n does
not exist, print the single number "-1" (without the quotes). Otherwise, print the answer to the problem: the number of such indexes i,
that i and ai are
both lucky numbers.

Examples

input
7 4


output
1


input
4 7


output
1


Note

A permutation is an ordered set of n elements, where each integer from 1 to n occurs
exactly once. The element of permutation in position with index i is denoted as ai (1 ≤ i ≤ n).
Permutation a is lexicographically smaller that permutation b if
there is such a i(1 ≤ i ≤ n),
that ai < bi,
and for any j (1 ≤ j < i) aj = bj.
Let's make a list of all possible permutations of n elements and sort it in the order of lexicographical increasing. Then the lexicographically k-th
permutation is the k-th element of this list of permutations.

In the first sample the permutation looks like that:

1 2 3 4 6 7 5

The only suitable position is 4.

In the second sample the permutation looks like that:

2 1 3 4

The only suitable position is 4.

当n大于13时,1到n这个数列真正排列的只有后面13个数字因为13! > k;所以用数位dp求出1到n-13上满足条件的数的个数。在用逆康拓展开求出后面13个数字第k个排列的情况,在求满足条件的数的个数.如果n <=13直接用逆康拓展开求出它第K个排列

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#define maxn 100005
#define INF 1e18
using namespace std;
typedef long long ll;

int dp[15][10], kk[20], vis[20], d[15];
void Init(){

d[0] = 1;
for(int i = 1; i <= 12; i++)
d[i] = d[i-1] * i;
dp[1][4] = dp[1][7] = 1;
for(int i = 2; i <= 10; i++){
dp[i][4] += dp[i-1][4] + dp[i-1][7];
dp[i][7] += dp[i-1][4] + dp[i-1][7];
dp[i][0] += dp[i-1][4] + dp[i-1][7] + dp[i-1][0];
}
}
int Query(int m){

int num[15];
int cnt = 0;
while(m){
num[cnt++] = m % 10;
m /= 10;
}
int ans = dp[cnt][0];
for(int i = cnt-1; i >= 0; i--){
if(num[i] > 7)
ans += dp[i+1][7];
if(num[i] > 4)
ans += dp[i+1][4];
if(num[i] != 4 && num[i] != 7)
break;
}
return ans;
}
bool judge(int m){
while(m){
int d = m % 10;
if(d != 4 && d != 7)
return false;
m /= 10;
}
return true;
}
int main(){

//	freopen("in.txt", "r", stdin);
Init();
int n, k;
scanf("%d%d", &n, &k);
if(n <= 12){
ll p = 1;
for(int i = 1; i <= n; i++){
p *= i;
}
if(k > p){
puts("-1");
return 0;
}
}
int ans = 0;
if(n > 13)
ans += Query(n - 12);
int p = 0;
int mins = n - 12 >= 1 ? n - 12 : 1;
for(int i = mins; i <= n; i++)
kk[p++] = i;
k--;
for(int i = p-1; i >= 0; i--){
int h = k / d[i];
int v, cnt = 0;
for(int j = 0; j < p; j++){
if(vis[j] == 0){
if(cnt == h){
vis[j] = 1;
if(judge(kk[j]) && judge(mins+(p-1-i))){
ans++;
}
break;
}
cnt++;
}
}
k %= d[i];
}
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: