比赛链接:

https://ac.nowcoder.com/acm/contest/32708

D.Divisions

题目大意:

将一个序列分成两个子序列,要求第一个子序列非递减,第二个子序列非递增,设 \(k\) 为满足要求的分类总数。
现告诉 \(k\),要求构造出满足条件的序列,长度不超过 365。

思路:

构造题。若一个非递减序列中的每个元素的个数为 \(a_1, a_2, ..., a_p\),则该序列的分类总数为 \(1 + (2^{a_1} - 1) + (2^{a_2} - 1) + ... + (2^{a_p} - 1)\)
0 和 1 要特判,其它的都可以直接构造。

代码:

#include <bits/stdc++.h>
using namespace std;
int k;
int main(){
    cin >> k;
    if (k == 0) cout << "5\n2 3 1 4 2\n";
    else if (k == 1) cout << "6\n1 1 4 5 1 4\n";
    else{
        k -- ;
        int p = 1;
        vector <int> ans;
        while (k){
            int cnt = 1;
            while ( (1 << cnt) - 1 <= k ){
                cnt ++ ;
            }
            cnt --;
            k -= (1 << cnt) - 1;
            for (int i = 1; i <= cnt; i ++ )
                ans.push_back(p);
            p ++ ;
        }
        cout << ans.size() << "\n";
        for (int i = 0; i < ans.size(); i ++ )
            cout << ans[i] << " \n"[i == ans.size() - 1];
    }
    return 0;
}

K.King of Gamers

题目大意:

\(n\) 场比赛,胜利的期望 \(x = \frac{a}{b}\),设当前比到第 \(i\) 场,在这之前胜了 \(k\) 场,当 \(\frac{k}{i} <= x\) 时,第 \(i\) 场会赢,否则会输,问最后赢多少场。

思路:

\(\frac{k}{n - 1} <= \frac{a}{b}\),可以得到 \(k <= \lfloor (n - 1) * \frac{a}{b} \rfloor\),第 \(i\) 场赢,所以结果应该是 \((n - 1) * a / b + 1\)
\(\frac{k}{n - 1} > \frac{a}{b}\),可以得到 \(k > \lceil (n - 1) * \frac{a}{b} \rceil\),第 \(i\) 场输,所以结果也是 \((n - 1) * a / b + 1\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL T, n, a, b;
void solve(){
    cin >> n >> a >> b;
    cout << (n - 1) * a / b + 1 << "\n";
}
int main(){
    cin >> T;
    while (T -- )
        solve();
    return 0;
}
posted on 2022-05-10 18:43  Hamine  阅读(323)  评论(0编辑  收藏  举报