定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
现在想知道在1...n的第k小的排列(permutation,https://en.wikipedia.org/wiki/Permutation)中,有多少个幸运数字所在的位置的序号也是幸运数字。
解法:康拓展开模拟即可,,最多置换了13位(全排列超过了1e9,前面的直接枚举所有幸运数字)
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pli pair<long long,int> #define pi acos(-1.0) #define ll long long #define mod (998244353) #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=3200+10,maxn=1000000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; ll f[N]; void init() { f[0]=f[1]=1; for(int i=2;i<=13;i++) { f[i]=f[i-1]*i; // printf("%lld ",f[i]); } // puts(""); } int cal(ll x,ll y) { while(x) { if(x%10!=4&&x%10!=7)return 0; x/=10; } while(y) { if(y%10!=4&&y%10!=7)return 0; y/=10; } return 1; } int main() { init(); // printf("%d\n",cal(4,4)); ll n,k,ans=0; scanf("%lld%lld",&n,&k); k--; vector<ll>v; for(ll i=max(1ll,n-13+1);i<=n;i++)v.pb(i); for(ll i=max(1ll,n-13+1);i<=n;i++) { // printf("%lld\n",f[n-i]); ll x=k/f[n-i]; ll r=k%f[n-i]; k=r; sort(v.begin(),v.end()); // for(int j=0;j<v.size();j++)printf("%d ",v[j]); // printf("%d+++%d++++%d--%d\n",i,x,v[x],cal(i,v[x])); ans+=cal(i,v[x]); v.erase(v.begin()+x); } v.clear(); for(int i=1;i<=10;i++) { for(int j=0;j<(1<<i);j++) { ll res=0; for(int k=0;k<i;k++) { if((j>>k)&1)res=res*10+4; else res=res*10+7; } v.pb(res); } } // for(int i=0;i<v.size();i++)printf("%lld\n",v[i]); sort(v.begin(),v.end()); for(int i=0;i<v.size();i++) if(v[i]<=max(0ll,n-13)) ans++; printf("%lld\n",ans); return 0; } /******************** ********************/