LeetCode第 91 场双周赛题解

目录

  • 2465. 不同的平均值数目
  • 2466. 统计构造好字符串的方案数
  • 2467. 树上最大得分和路径
  • 2468. 根据限制分割消息

2465. 不同的平均值数目

LeetCode第 91 场双周赛题解_第1张图片
模拟一下即可

class Solution {
public:
    int distinctAverages(vector<int>& nums) {
        set<double>st;
        sort(nums.begin(),nums.end());
        int l=0,r=nums.size()-1;
        while(l<r)
        {
            st.insert((nums[l]+nums[r])*1.0/2);
            l++,r--;
        }
        return st.size();
    }
};

2466. 统计构造好字符串的方案数

LeetCode第 91 场双周赛题解_第2张图片
爬楼梯的变种题。
f[i]表示字符串长度为i的方案数

class Solution {
public:
    const int mod=1e9+7;
    int countGoodStrings(int low, int high, int zero, int one) {
        vector<int>f(high+10,0);
        f[0]=1;
        for(int i=1;i<=high;i++)
        {
            if(i-zero>=0)f[i]=(f[i]+f[i-zero])%mod;
            if(i-one>=0)f[i]=(f[i]+f[i-one])%mod;
        }
        int res=0;
        for(int i=low;i<=high;i++)res=(res+f[i])%mod;
        return res;
    }
};

2467. 树上最大得分和路径

LeetCode第 91 场双周赛题解_第3张图片
LeetCode第 91 场双周赛题解_第4张图片
LeetCode第 91 场双周赛题解_第5张图片
由题意可知,B只有一种路径,那么我们可以先记录这条路径,然后枚举A可以走的每一种路径,同时用hash存b对应的情况,模拟一下即可。
有一个小细节需要注意,如果用邻接表存双向边的树时,判断叶子结点不能用u==-1判断,记录一下每个节点的度,发现叶子节点的度为1。进而判断。

class Solution {
public:
    static const int N=1e5+10;
    int h[N],e[N<<1],ne[N<<1],idx;
    int outd[N];
    int w[N];
    vector<int>p;
    map<int,int>mp;
    int maxv=-1e5;
    int n;
    void add(int a,int b)
    {
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs(int u,int fa,vector<int>&v)
    {
        v.push_back(u);
        if(u==0)
        {
            p=v;
            return;
        }
        for(int i=h[u];~i;i=ne[i])
        {
            int j=e[i];
            if(j==fa)continue;
            dfs(j,u,v);
        }
        v.pop_back();
    }
    void dfs(int u,int fa,int sum,int cnt)
    {
        int t=0;
        if(cnt<p.size()&&u==p[cnt])t=w[u]/2;//同时
        else if(!mp[u]||cnt>=p.size())t=w[u];
        sum+=t;
        if(cnt<p.size())mp[p[cnt]]++; 
        if(outd[u]<2&&u)maxv=max(maxv,sum);
        for(int i=h[u];~i;i=ne[i])
        {
            int j=e[i];
            if(j==fa)continue;
            dfs(j,u,sum,cnt+1);
        }
        if(cnt<p.size())mp[p[cnt]]--;
        sum-=t;
    }
    int mostProfitablePath(vector<vector<int>>& edges, int bob, vector<int>& amount) {
        memset(h,-1,sizeof h);
        n=edges.size();
        for(int i=0;i<edges.size();i++)
        {
            int a=edges[i][0],b=edges[i][1];
            add(a,b),add(b,a);
            outd[a]++,outd[b]++;
        }
        for(int i=0;i<amount.size();i++)w[i]=amount[i];
        vector<int>v;
        dfs(bob,-1,v);
        for(auto x:p)cout<<x<<' ';
        dfs(0,-1,0,0);
        return maxv;
    }
};

2468. 根据限制分割消息

LeetCode第 91 场双周赛题解_第6张图片
暴力模拟一下,也没有别的什么技巧。

class Solution {
public:
    vector<int>p;
    vector<string> splitMessage(string message, int limit) {
        if(limit<=5)return{};
        int n=message.size();
        p.resize(n+1);
        for(int i=1;i<10&&i<=n;i++)p[i]=p[i-1]+1;
        for(int i=10;i<100&&i<=n;i++)p[i]=p[i-1]+2;
        for(int i=100;i<1000&&i<=n;i++)p[i]=p[i-1]+3;
        for(int i=1000;i<10000&&i<=n;i++)p[i]=p[i-1]+4;
        vector<string>res;
        for(int i=1;i<=n;i++)//枚举段数
        {
            string s2=to_string(i);
            if(3+s2.size()*2>limit)break;
            int sz=message.size()+i*(3+s2.size())+p[i];
            if(limit*(i-1)<sz&&limit*i>=sz)
            {
                int scnt=limit-(3+s2.size());//a+message的长度
                for(int j=1,idx=0;j<=i;j++)
                {
                    string s1=to_string(j);
                    int t=scnt-s1.size();//message的长度
                    string s;
                    s=message.substr(idx,t)+'<'+s1+'/'+s2+'>';
                    res.push_back(s);
                    idx+=t;
                }
                break;
            }
        }
        return res;
    }
};

你可能感兴趣的:(算法,C++,LeetCode,leetcode,深度优先,算法)