题解 | #Bus Number#

Bus Number

https://ac.nowcoder.com/acm/problem/229276

题意

给你一串数字,这个数字包含的数位为,然后每个数位出现的次数为,然后问你有多少个数字满足,每个都出现过,并且出现的次数都小于等于

思路

枚举每个出现的次数,然后排列组合,然后去除前导零的情况

代码

/**
 *    author: andif
 *    created: 27.08.2023 16:26:46
**/
#include<bits/stdc++.h>
using namespace std;

#define de(x) cerr << #x << " = " << x << endl
#define dd(x) cerr << #x << " = " << x << " "
#define rep(i, a, b) for(int i = a; i < b; ++i)
#define per(i, a, b) for(int i = a; i > b; --i)
#define mt(a, b) memset(a, b, sizeof(a))
#define sz(a) (int)a.size()
#define fi first
#define se second
#define qc ios_base::sync_with_stdio(0);cin.tie(0)
#define eb emplace_back
#define all(a) a.begin(), a.end()
using ll = long long;
using db = double;
using pii = pair<int, int>;
using pdd = pair<db, db>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
const db eps = 1e-9;
const int N = 21;

int main() {
    vector<vl> c(N, vl(N, 0));
    c[1][0] = c[1][1] = 1;
    rep(i, 2, N) {
        c[i][0] = 1;
        rep(j, 1, N) {
            c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
        }
    }
    string n; cin >> n;
    if (sz(n) == 1) return cout << "1" << '\n', 0;
    vi cnt(10);
    vi a;
    rep(i, 0, sz(n)) {
        int x = n[i] - '0';
        cnt[x]++;
        if (cnt[x] == 1) {
            a.eb(x);
        }
    }
    sort(all(a));
    // rep(i, 0, sz(a)) {
    //     dd(i), de(a[i]);
    // }
    ll ans = 0;
    auto dfs = [&] (auto self, vi& b) -> void {
        if (sz(b) == sz(a)) {
            // rep(i, 0, sz(b)) dd(i), de(b[i]);
            int t = std::accumulate(all(b), 0);
            ll xx = 1;
            rep(i, 1, sz(b)) {
                xx *= c[t][b[i]];
                t -= b[i];
            }
            ans = ans + xx;
            if (!a[0]) {
                int h = std::accumulate(all(b), 0) - 1;
                ll yy = 1;
                rep(i, 1, sz(b)) {
                    yy *= c[h][b[i]];
                    h -= b[i];
                }
                ans = ans - yy;
            }
            return;
        }
        int i = sz(b);
        rep(j, 1, cnt[a[i]] + 1) {
            b.eb(j);
            self(self, b);
            b.pop_back();
        }
    };
    vi b;
    dfs(dfs, b);
    cout << ans << '\n';
    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务