LeetCode第 91 场双周赛题解

115 篇文章 3 订阅
35 篇文章 3 订阅

2465. 不同的平均值数目

在这里插入图片描述
模拟一下即可

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. 统计构造好字符串的方案数

在这里插入图片描述
爬楼梯的变种题。
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. 树上最大得分和路径

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由题意可知,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. 根据限制分割消息

在这里插入图片描述
暴力模拟一下,也没有别的什么技巧。

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leimingzeOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值