P3048 [USACO12FEB]Cow IDs S

题意

FJ给他的奶牛用二进制进行编号,每个编号恰好包含K 个"1" (1 <= K <= 10),且必须是1开头。FJ按升序编号,第一个编号是由K个"1"组成。

请问第N(1 <= N <= 10^7)个编号是什么。

首先手动模拟样例,发现如果从后往前枚举,当第i位为1后面总的情况都是C(i-1,k),k为当前1个数,每确定一个1,k都会减小。
那么不就剩暴力了吗,预处理组合数,k只需要10个,所以底数即使开1e6个都是够的,也不要怕爆int,因为能爆int得数我们不可能取,所以爆int的数为负数,我们一个简单判断就可以剔除。唯独k为1的情况我们特别考虑,因为1的时候答案是固定的,长度必为n,而n可能是1e7,我们直接输出即可,k越大,最后长度越短。

//
// Created by SANZONG on 2021/8/9.
//

#include "bits/stdc++.h"

#define int long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 2e6;
const int MAXN = 3e5 + 100;
int c[MAXN][20];



void init() {
    
    
    c[0][0] = 0;
    for (int i = 1; i <= 300000; ++i) {
    
    
        c[i][0] = 1;
        for (int j = 1; j <= 11; ++j) {
    
    
            c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
        }
    }
}

int vis[N];
void solve() {
    
    

    int n, k;
    cin >> n >> k;
    n -= 1;
    if (k == 1)
    {
    
    
        cout << 1;
        for (int i = 1; i <= n; ++i) {
    
    
            cout << '0' ;
        }
        cout << endl;
        return;
    }
    int s = 0;
    for (int i = 300000; i >= 1; --i) {
    
    
        if (c[i-1][k] <= n && c[i-1][k] >= 0) {
    
    
            if (!s)
                s = i;
            vis[i] = 1;
            n -= c[i-1][k];
            k--;
        }
    }
    for (int i = s; i >= 2; --i) {
    
    
        cout << vis[i];
    }
    cout << endl;
}

signed main() {
    
    
    ios::sync_with_stdio(0);
    //freopen("in.txt", "r", stdin);
//    prework();
    init();
    solve();
}

猜你喜欢

转载自blog.csdn.net/weixin_45509601/article/details/119606898
ids