给定移动字符串,可将字符串中的_替换成任何字符,求移动后的距离原点的最大曼哈顿距离。
因为曼哈顿距离只关注|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; } };
要求数组和的首和尾数位都为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; } };
给定图,要求最短路,同时需要满足最短路不会有超过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; } };
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; } };
浙公网安备 33010602011771号