力扣 第507场周赛(A~D)

A:移动后的最大曼哈顿距离

给定移动字符串,可将字符串中的_替换成任何字符,求移动后的距离原点的最大曼哈顿距离。

因为曼哈顿距离只关注|x|+|y|,所以我们可以先走完全部的,然后再将所有的_替换成沿着最终点所在象限的方向移动即可。

那么ans=|x'|+|y'|+cnt

class Solution {
public:
    int maxDistance(string moves) {
        int x=0,y=0;
        int cnt=0;
        for(char c:moves){
            if(c=='U')
                y++;
            else if(c=='D')
                y--;
            else if(c=='L')
                x--;
            else if(c=='R')
                x++;
            else
                cnt++;
        }
        return abs(x)+abs(y)+cnt;
    }
};
View Code

B:求和后首尾数字相同的有效子数组 I

要求数组和的首和尾数位都为x的子数组数目,直接模拟即可,加上前缀和优化掉一维,能够通过1e3的数据。

class Solution {
public:
    int countValidSubarrays(vector<int>& nums, int x) {
        int n=nums.size();
        vector<long long> sum(n+1,0);
        for(int i=1;i<=n;i++){
            sum[i]=sum[i-1]+nums[i-1];
        }
        int ans=0;
        for(int i=0;i<n;i++){
            for(int j=i;j<n;j++){
                long long s=sum[j+1]-sum[i];
                if(s%10!=x)
                    continue;
                while(s>=10)
                    s/=10;
                if(s==x)
                    ans++;
            }
        }
        return ans;
    }
};
View Code

C:最多 K 个连续相同字符的最短路径

给定图,要求最短路,同时需要满足最短路不会有超过k个连续相同的字符。有向正权图,可用dijkstra,带上节点状态。

typedef long long LL;
struct cmp{
    bool operator()(tuple<LL,LL,char,LL> a,tuple<LL,LL,char,LL> b){
        return get<0>(a) > get<0>(b);
    }
};
class Solution {
public:
    int shortestPath(int n, vector<vector<int>>& edges, string labels, int k) {
        vector<vector<pair<LL,LL>>> g(n);
        for(LL i=0;i<edges.size();i++){
            auto u=edges[i][0],v=edges[i][1],w=edges[i][2];
            g[u].push_back({v,w});
        }
        map<tuple<int,char,int>,int> dis;
        //(当前dis,当前节点,末尾字符,连续次数)
        priority_queue<tuple<LL,LL,char,LL>,vector<tuple<LL,LL,char,LL>>,cmp> pq;
        pq.push({0,0,labels[0],1});
        dis[{0,labels[0],1}]=0;
        while(pq.size()){
            auto t=pq.top();
            pq.pop();
            LL d=get<0>(t),u=get<1>(t);
            char c=get<2>(t),times=get<3>(t);

            tuple<int,char,int> curState={u,c,times};
            if(d>dis[curState]) continue;
            if(u==n-1) return d;
            for(LL i=0;i<g[u].size();i++){
                LL v=g[u][i].first,w=g[u][i].second;
                char nc=labels[v];
                int ntimes;
                if(nc==c){
                    ntimes=times+1;
                    if(ntimes>k)
                        continue;
                }else
                    ntimes=1;
                int nd=d+w;
                tuple<int,char,int> nState={v,nc,ntimes};
                if(!dis.count(nState) || nd<dis[nState]){
                    dis[nState]=nd;
                    pq.push({nd,v,nc,ntimes});
                }
                
            }
        }
        return -1;
    }
};
View Code

D:最大总价值

给定n个递减的等差数列,要从中取m个数,使得最终答案最大。

朴素想法为建堆,n个数放进去,然后每次取最大,然后递减再放进去,时间复杂度为O(mlogn),此处m为1e9,并不可行。

时间复杂度要求log,那么我们开始考虑二分。给定x,表示我们拿走所有的大于x的数,能否保证拿够m个?

如此,check函数能写,得到最终的x后也能够计算出答案。

typedef long long LL;
LL MOD=1e9+7;
class Solution {
public:
    LL maxTotalValue(vector<int>& value, vector<int>& decay, int m) {
        LL mx=*max_element(value.begin(),value.end());
        LL l=-1,r=mx;
        LL n=value.size();
        auto get_cnt=[&](LL v,LL d,LL x){
            if(v<x) return LL(0ll);
            return (v-x)/d + 1;
        };
        auto check=[&](LL x){
            LL sum=0;
            for(LL i=0;i<n;i++){
                sum+=get_cnt(value[i],decay[i],x);
                if(sum>=m)
                    return true;
            }
            return false;
        };
        while(l<r){
            LL mid=l+r+1>>1;
            if(check(mid))
                l=mid;
            else
                r=mid-1;
        }
        LL ans=0;
        LL cnt=0;
        if(l<0){
            //不够,把所有大于0的都加上
            for(LL i=0;i<n;i++){
                LL v=value[i],d=decay[i];
                LL t=v/d+1;
                LL tv=v-(v)/d*d;
                ans=ans+((v+tv)*t/2)%MOD;
                ans%=MOD;
            }
        }else{
            for(LL i=0;i<n;i++){
                LL v=value[i],d=decay[i];
                if(v<=l)
                    continue;
                LL t=(v-(l+1))/d+1;
                LL tv=v-(v-(l+1))/d*d;
                cnt+=t;
                ans=ans+((v+tv)*t/2)%MOD;
                ans%=MOD;
            }
            ans+=(m-cnt)*l;
            ans%=MOD;
        }
        return ans;
    }
};
View Code

 

posted on 2026-06-21 15:50  greenofyu  阅读(2)  评论(0)    收藏  举报