1. 程式人生 > >洛谷P3048 [USACO12FEB]牛的IDCow IDs

洛谷P3048 [USACO12FEB]牛的IDCow IDs

book 方案 對數 right oss 限制 是什麽 compute blue

P3048 [USACO12FEB]牛的IDCow IDs

    • 12通過
    • 67提交
  • 題目提供者lin_toto
  • 標簽USACO2012
  • 難度普及/提高-
  • 時空限制1s / 128MB

討論 題解

最新討論更多討論

  • 誰能解釋一下這個樣例啊....

題目描述

Being a secret computer geek, Farmer John labels all of his cows with binary numbers. However, he is a bit superstitious, and only labels cows with binary numbers that have exactly K "1" bits (1 <= K <= 10). The leading bit of each label is always a "1" bit, of course. FJ assigns labels in increasing numeric order, starting from the smallest possible valid label -- a K-bit number consisting of all "1" bits. Unfortunately, he loses track of his labeling and needs your help: please determine the Nth label he should assign (1 <= N <= 10^7).

FJ給他的奶牛用二進制進行編號,每個編號恰好包含K 個"1" (1 <= K <= 10),且必須是1開頭。FJ按升序編號,第一個編號是由K個"1"組成。

請問第N(1 <= N <= 10^7)個編號是什麽。

輸入輸出格式

輸入格式:

  • Line 1: Two space-separated integers, N and K.

輸出格式:

輸入輸出樣例

輸入樣例#1:
7 3 
輸出樣例#1:
10110 
分析:首先有一個很簡單的結論:一個只有0和1的數字串,只有1對數字串大小有影響,0沒有影響。很簡單證明,大小取決於1的位置和數量。
這道題有一個限制:第一位必須是0,那麽我們先將這個串用足夠大小保存,足夠大的話我們可以添加前導0,到最後從第一個非0位輸出即可,也就是說我們要找到一個m,使得C(m,k) >= n,這個可以用二分實現,我們先弄一個m位的全是0的串。然後考慮C(i-1,k)的意義,即還剩i-1位可以填k個1的方案數,也就是說我們還有C(i,k)個不同大小的數,如果C(i-1,k) < n,則說明剩下的數還不夠n個,我們不能找到第n大的數,於是我們在i位填1,那麽這個數就是能夠出現的C(i-1,k)個數中最大的,n-=C(i-1,k),k--,如果C(i-1,k) >= n,說明後面還能找到第n大的,我們填0即可,就這樣模擬一下就好了。
不過這個組合數會非常大,還會爆long long,需要分類討論進行二分.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

long long n, k, f[50][20], m;
long long num[110000], cnt;

long long Combination(long long n, long long m)
{
    long long ans = 1;
    for (long long i = n; i >= (n - m + 1); --i)
        ans 
*= i; while (m) ans /= m--; return ans; } int main() { scanf("%lld%lld", &n, &k); if (k == 1) { for (int i = n; i; i--) { if (i == n) printf("1"); else printf("0"); } return 0; } else { if (k == 10) { long long l = 1, r = 600; while (l <= r) { long long mid = (l + r) >> 1; if (Combination(mid, k) >= n) { m = mid; r = mid - 1; } else l = mid + 1; } } else { if (k >= 7) { long long l = 1, r = 1000; while (l <= r) { long long mid = (l + r) >> 1; if (Combination(mid, k) >= n) { m = mid; r = mid - 1; } else l = mid + 1; } } else { long long l = 1, r = 7000; while (l <= r) { long long mid = (l + r) >> 1; if (Combination(mid, k) >= n) { m = mid; r = mid - 1; } else l = mid + 1; } } } for (long long i = m; i; i--) { long long t = Combination(i - 1, k); if (t < n) { num[i] = 1; n -= t; k--; if (!cnt) cnt = i; } if (!k || !n) break; } for (long long i = cnt; i; i--) printf("%d", num[i]); } return 0; }

 

洛谷P3048 [USACO12FEB]牛的IDCow IDs