4.4隊內測

nameko發表於2024-04-07
#include<bits/stdc++.h>
using namespace std;
long long p[2000], sz, Ans, n, k;
long long q[10000];//儲存生成的index數 
long long fac[15];//階乘 
int size;
void dfs(int k,long long s){//預處理所有的的index數
    q[++size] = s;
    if(k == 11){
        return;
    } 
    dfs(k + 1, s * 10 + 4);
    dfs(k + 1, s * 10 + 7);
} 
void init(){//同上
    dfs(1,0); 
    sort(q + 1, q + size + 1);
} 
bool check(long long n) {//判斷n是否為index數
    stringstream ss;//字串流 
    string s;
    ss << n;
    ss >> s;
    bool f = 1;
    for(int i = 0; i < s.size(); i++) 
        if(s[i]!='4' && s[i]!='7'){
            f = 0; break;
        }
    return f;
} 
int main(){
    fac[0] = 1;
    for(int i = 1; i <= 12; i ++) fac[i] = i * fac[i - 1];//預處理 計算階乘
    scanf("%lld%lld", &n ,&k);
    k--; //注意 隊內測時這掛分了QAQ
    long long last = 1;
    init();
    for (int i = 1; i <= size; i++)
        if(q[i] < max(1ll, n - 13)&& check(q[i]))Ans++;//統計 n-13位前index數 
        
        for(int i = max(1ll,n-13); i < n; i++){
            long long tmp = fac[n-i];
            long long l = 0, r = n-i, mid, ans = 0;
            while(l <= r){//二分 
                int mid = (l + r) >> 1;
                if(mid * tmp > k) r = mid - 1;
                else ans = mid, l = mid + 1;
            }
        k -= ans * tmp;
        last += ans;
        ans ++;
        for(int j = 1; j <= sz; j++)
            if (p[j]<= ans)ans ++;
        p[++sz] = ans;
        sort(p + 1, p + 1+ sz);
        if(check(i)&&check(max(0ll, n - 14)+ans)) Ans++;
    }
    long long ans = 1;
    for (int j = 1; j <= sz; j++)
    if(p[j]<=ans) ans ++;
    if(check(n) && check(max(0ll, n-14)+ans))Ans ++;
            
    if(k > 0) puts("-1");
    else printf("%lld",Ans);    
    return 0; 
} 

相關文章