第五期竞赛第四题,6169. 最长优雅子数组,6170. 会议室

106 阅读1分钟

6170. 会议室 III - 力扣(LeetCode)

 调了好久终于调出来了,根据题目中所说的来做就行,需要注意的就是要在未被占用的会议室中选择一个编号最小的,所以需要另开一个优先队列q1来储存空闲的会议室编号,再开一个优先队列q存每个正在开的会议,枚举每一个会议,将队列中结束时间小于该会议开始时间的弹出并将会议室编号放入q1,q1size为0的话,我们就要强行将q中的一个会议室给空出来,最后比较一下输出编号就可以了

ll cnt[105];
class Solution {
public:
    int mostBooked(int n, vector<vector<int>>& meetings) {
        ll ma=1,maxx=0,m=meetings.size();
        for(int i=1;i<=100;i++) cnt[i]=0;
        for(int i=0;i<meetings.size();i++){
            a[i+1].l=meetings[i][0];
            a[i+1].r=meetings[i][1];
        }
        sort(a+1,a+m+1,cmp);
        priority_queue<node>q;
        priority_queue<ll,vector<ll>,greater<ll> >q1;
        for(int i=1;i<=n;i++) q.push(node{0,0,i});
        for(int i=1;i<=m;i++){
            ll u=a[i].l;
            while(!q.empty()&&q.top().r<=u){
                q1.push(q.top().id);q.pop();
            }
            if(q1.size()<=0){
                u=q.top().r;
                q1.push(q.top().id);q.pop();
            }
            if(!q1.empty()){
               // cout<<a[i].l<<" "<<a[i].r<<" "<<q.top().r<<" "<<q.size()<<" "<<q1.top()<<" "<<i<<endl;
                a[i].id=q1.top();cnt[q1.top()]++;
                a[i].r=u+a[i].r-a[i].l;
                a[i].l=u;
                q1.pop();
                q.push(a[i]);
            }
        }
        ll ans=0;
        maxx=0;
        for(int i=1;i<=n;i++){
           // cout<<cnt[i]<<" "<<i<<endl;
            if(maxx<cnt[i]) ans=i-1,maxx=cnt[i];
        }
        return ans;
    }
};

6169. 最长优雅子数组 - 力扣(LeetCode)

考虑lr这段区间内,只要每一位二进制的和都不超过1那就符合条件,预处理出前缀和之后双指针更新区间就可以

#include<bits/stdc++.h>
#define ll long long
class Solution {
public:
    int longestNiceSubarray(vector<int>& nums) {
        ll sum[100005][33],n=nums.size();
        for(int i=0;i<=100000;i++)
        for(int j=0;j<32;j++) sum[i][j]=0;
        for(int i=0;i<nums.size();i++){
           /* ll w=nums[i];
            while(w){
                cout<<w%2;
                w/=2;
            }
            cout<<endl;*/
            for(int j=0;j<32;j++){
                if((nums[i]&(1<<j))==(1<<j)) sum[i+1][j]=sum[i][j]+1;
                else sum[i+1][j]=sum[i][j];
               //cout<<sum[i+1][j]<<" "<<i+1<<" "<<j<<" "<<(1<<j)<<" "<<(nums[i]&(1<<j))<<endl;
            }
        }
        ll ans=1,l=1;
        for(ll i=1;i<=n;i++){
            while(l<=i){
                bool flag=1;
                if(l==i) break;
                for(int j=0;j<32;j++){
                    //if(i==5) cout<<sum[i][j]<<" "<<sum[l-1][j]<<" "<<i<<" "<<j<<" "<<l<<endl;
                    if(sum[i][j]-sum[l-1][j]>1){flag=0;break;}
                    //else {cout<<sum[i][j]<<" "<<sum[l-1][j]<<" "<<i<<" "<<j<<" "<<l<<endl;}
                }
                if(flag) break;
                l++;
            }
           // cout<<i<<" "<<l<<endl;
            ans=max(ans,i-l+1);
        }
        return ans;
    }
};

第五期竞赛第四题

image.png  总的能完成的任务量是x(1+1/k+1/k^2+...+1/k^(t-1)),也就是\frac{x(1+k+k^{2}+...+k^{t-1})}{k^{t-1}},可以看出这是一个等比数列求和,最后因为要>=n所以可以化成这样kx/(k-1)>=n+1/((1-k)*(k^(t-1)),我们可以先算出kx/(k-1)>=n时的x来,然后让x一步一步增加知道满足条件就可以,这样是不会超时的

image.png