牛客编程巅峰赛S2第4场

链接

A

牛牛最近很喜欢掷硬币,由于他今天很无聊,所以他在家掷了n次硬币,如果这n次硬币全部朝上或者全部朝下牛牛就很开心,请问牛牛开心的概率是多少。(每次掷硬币朝上的概率与朝下的概率相同)
n<=1e9
对于每个n,返回一个严格四舍五入保留两位小数的字符串。
比如概率为0.372的话,返回字符串"0.37"。
概率为0.957的话,返回字符串"0.96"。
(注意,返回的字符串不带引号)

不会sstream,难顶

class Solution {
public:
    /**
     * 返回一个严格四舍五入保留两位小数的字符串
     * @param n int整型 n
     * @return string字符串
     */
    string Probability(int n) {
        // write code here
        double p = 1.0;
        for(int i=0; i<n; i++){
            p/=2;
            if(p<0.000001)
                break;
        }
        p *= 2;
        p *= 100; //保留两位
        int ans  = floor(p+0.5);
        string res = to_string(ans);
        if(res.size()==3) return "1.00";
        
        if(res.size()<2) res = "0"+res;
        return "0."+res;
    }
};

B

牛牛有n(2<= n <= 10^5)个玩偶,牛牛打算把这n个玩偶摆在桌子上,桌子的形状的长条形的,可以看做一维数轴。 桌子上有 M 个互不相交的区间(1≤M≤10^5)
这些区间上面可以放玩偶。一个位置只能放一个玩偶,玩偶之间的距离越大越美观,牛牛想最大化 D 的值,其中 D 为最近的两个玩偶之间的距离。请帮牛牛求出 D 的最大可能值。

垃圾题,不给下界,直接二分就好了

/**
 * struct Interval {
 *	int start;
 *	int end;
 *	Interval(int s, int e) : start(start), end(e) {}
 * };
 */
using ll = long long;
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 玩偶数
     * @param m int整型 区间数
     * @param intervals Interval类vector 表示区间
     * @return int整型
     */
    int mm;
    int nn;
    bool chek(ll gap, vector<Interval>& a){
        ll pos = 0;
        int cnt=0;
        for(int i=0; i<mm; i++){
            pos = max(pos, ll(a[i].start));
            while(pos<=ll(a[i].end)){
                cnt += 1;
                pos += gap;
                if(cnt>=nn) return 1;
            }
        }
        return 0;
    }
    int doll(int n, int m, vector<Interval>& a) {
        // write code here
        sort(a.begin(), a.end(), [](Interval&a, Interval&b){
            return a.start<b.start;
        });
        mm = m;
        nn = n;
        ll  l = 0LL;
        ll r = 2147483648LL;
        ll ans=1;
        while(l<=r){
            ll mid = (l+r)>>1LL;
            if(chek(mid, a))
            {
                ans = max(ans, mid);
                l = mid+1;
            }
            else r = mid-1;
        }
        return ans;
    }
};

垃圾,把推出来的直接乘的那儿脑残的写了个乘法逆元,从开始卡到结尾没看出来
离谱 其实就直接把和的式子拆开,就发现可以有三部分组成就好了
放一张图,和我的思路一样,题解区找到的,自己懒得写了23333

using LL = long long;
LL mod = 1e9+7;
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 多次求交叉乘
     * @param a int整型vector a1,a2,...,an
     * @param query int整型vector l1,r1,l2,r2,...,lq,rq
     * @return int整型vector
     */
    vector<int> getSum(vector<int>& a, vector<int>& query) {
        // write code here
        int n = a.size();
        vector<LL> suf(n+2, 0LL);
        for(int i=n-1; i>=0; i--){
            suf[i+1] = suf[i+2]+a[i];
            suf[i+1] %= mod;
        }
        vector<LL> ans(n+2, 0LL);
        for(int i=n-1; i>=0; i--){
            ans[i+1] = ans[i+2] + suf[i+2]*a[i];
            ans[i+1] %= mod;
        }

        vector<int> res(query.size()/2);
        for(int i=0; i*2<query.size(); i++){
            int l = query[i*2];
            int r = query[2*i+1];
            if(l==r){
               res[i]=0; 
                continue;
            }
            res[i] = (((ans[l]-((suf[l]-suf[r]+mod)%mod)*suf[r+1])%mod-ans[r])%mod+mod)%mod;
        }
        return res;
    }
};
posted @ 2020-11-27 22:51  CrosseaLL  阅读(60)  评论(0编辑  收藏  举报