B 莫的难题

题目地址:

https://ac.nowcoder.com/acm/contest/5881/B

基本思路:

刚刚看了一下别人的代码,发现自己蠢了,一直以为第25大应该是99,结果其实是59。一直在用错误的样例调代码,好像把对的代码调错了QAQ。
其实这题也不是很难,首先C(n, m)%1e9+7 (n>=m)这个就是个裸的组合数可以直接算出来,所以实际上就是求这五个数字能组成的数中的第k大就是了。然后对于每一位的数的数目实际上是确定的,我们稍微分析一下就能发现实际上就是一个进制转换,把这个第k大转化为5进制的形式然后就是对应实际那一位的第几大的数就是了。

参考代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false)
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)
#define INF (int)1e18

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

int mod = 1e9 + 7;
const int maxn = 210;
int qpow(int a,int x) {
  int ret = 1;
  while (x) {
    if (x & 1)
      ret = ret * a % mod;
    a = a * a % mod;
    x >>= 1;
  }
  return ret;
}
int fac[maxn],inv[maxn];
int init() {
  fac[0] = 1;
  for (int i = 1; i < maxn; i++)
    fac[i] = fac[i - 1] * i % mod;
  inv[maxn - 1] = qpow(fac[maxn - 1], mod - 2);
  for (int i = maxn - 2; i >= 0; i--)
    inv[i] = inv[i + 1] * (i + 1) % mod;
  return 0;
}
int c(int n,int m) {
  if (n < m) return 0;
  return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int n,m;
char key[10] = "12359";
signed main() {
  IO;
  init();
  int T;
  cin >> T;
  while (T--){
    cin >> n >> m;
    int kth = c(n,m) % mod;
    vector<int> res;
    while (kth){
      kth--; // 可以带几个数字算一下能发现这里要减一;
      res.push_back(kth % 5);
      kth /= 5;
    }
    reverse(res.begin(),res.end());
    for(auto it : res) cout << key[it];
    cout << '\n';
  }
  return 0;
}