3.11 leetcode第 248 场周赛

1920. 基于排列构建数组

  • 题目大意
    输出 a n s = [ n u m s [ n u m s [ 0 ] ] , n u m s [ n u m s [ 1 ] ] , n u m s [ n u m s [ 2 ] ] , n u m s [ n u m s [ 3 ] ] , n u m s [ n u m s [ 4 ] ] , n u m s [ n u m s [ 5 ] ] ] = [ n u m s [ 0 ] , n u m s [ 2 ] , n u m s [ 1 ] , n u m s [ 5 ] , n u m s [ 3 ] , n u m s [ 4 ] ] = [ 0 , 1 , 2 , 4 , 5 , 3 ] ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]] = [nums[0], nums[2], nums[1], nums[5], nums[3], nums[4]]= [0,1,2,4,5,3] ans=[nums[nums[0]],nums[nums[1]],nums[nums[2]],nums[nums[3]],nums[nums[4]],nums[nums[5]]]=[nums[0],nums[2],nums[1],nums[5],nums[3],nums[4]]=[0,1,2,4,5,3]

  • 思路

  • code

class Solution {
public:
    vector<int> buildArray(vector<int>& nums) {
        
        int n = nums.size();
        vector<int> ans;
        for(int i=0;i<n;i++)
        {
            ans.push_back(nums[nums[i]]);
        }
        return ans;
    }
};

1921. 消灭怪物的最大数量

  • 题目大意
    给出n个怪物的距离和速度,每一分钟可以消灭一个怪物,问最多能消灭多少个怪物。若有个一怪物距离为0视为已经死亡不能继续打怪了。
  • 思路
    边界没想清楚写了好久。
  • code
class Solution {
public:
    int eliminateMaximum(vector<int>& dist, vector<int>& speed) {
        int n = dist.size();
        int a[100010]={0};
        int maxn=0;
        for(int i=0;i<n;i++)
        {
            if(dist[i]%speed[i]==0) a[dist[i]/speed[i]-1]++;
            else a[dist[i]/speed[i]]++;
            maxn=max(maxn,dist[i]/speed[i]);
        }
        int x=0;
        if(a[0]>1) return 1;
        for(int i=0;i<=maxn;i++)
        {
            if(a[i]==0) continue;
            else x+=a[i];
            
            if(x>i+1) return i+1;
        }
        return n;
    }
};

1922. 统计好数字的数目

  • 题目大意
    求n位十进制数共有多少个完美数。其中,偶数位数字为偶数,奇数位数字为质数的数称为完美数。
  • 思路
    快速幂统计。
  • code
class Solution {
public:
    long long mod = 1e9+7;
    long long pw(long long x, long long p) {
            long long ans=1;
            while(p)
            {
                if(p&1) ans=(ans*x)%mod;
                x=(x*x)%mod;
                p>>=1;
            }
            return ans%mod;
    }
    int countGoodNumbers(long long n) {
        if(n%2==0) return pw(5,n/2)*pw(4,n/2)%mod;
        else return pw(5,n/2+1)*pw(4,n/2)%mod;
    }
};

1923. 最长公共子路径

  • 题目大意
    给定m个序列,求他们的最长公共子串。
  • 思路
    二分+hash
  • code
没过的代码
class Solution {
public:
    int longestCommonSubpath(int n, vector<vector<int>>& paths) {
        map<unsigned long long, int> p;
        unsigned long long base = 723457;
        int m = paths.size();
        int l=0,r=0;
        for(int i=0;i<paths.size();i++) r=max(r,int(paths[i].size()));
        unsigned long long pw[100010]={0};pw[0]=1;
        for(int i=1;i<=n;i++) pw[i]=pw[i-1]*base;
        int ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
           // cout<<mid<<' '<<l<<' '<<r<<endl;
            unsigned long long hash[100010];
            p.clear();
            int num=0;
            for(int i=0;i<m;i++)
            {
                hash[0]=paths[i][0];
                for(int j=1;j<paths[i].size();j++) hash[j]=hash[j-1]*base+paths[i][j];
                map<unsigned long long, int> pp;
                p[hash[mid-1]]++;pp[hash[mid-1]]++;
                for(int j=mid;j<paths[i].size();j++)
                {
                    p[hash[j]-hash[j-mid]*pw[mid]]++;
                    pp[hash[j]-hash[j-mid]*pw[mid]]++;
                }
                for(auto [u,v]:pp) if(v>=2) p[u]=p[u]-v+1;
            }
            int fl=0;
            for(auto [u,v]:p) if(v==m) fl=1;
            if(fl) {ans=max(ans,mid); l=mid+1;}
            else r=mid-1;
        }  
        return ans;
    } 
};
又是一个没过的代码
#define maxn 100005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)

ll h[maxn],b[maxn],h2[maxn],b2[maxn];
const ll mod=998244353;
const ll mod2=1000000007;
map <pair<int,int>,int> p;

const ll base=987654;
const ll base2=123456;

inline ll gh(int l,int r){return (h[r]-h[l-1]*b[r-l+1]%mod+mod)%mod;}
inline ll gh2(int l,int r){return (h2[r]-h2[l-1]*b2[r-l+1]%mod2+mod2)%mod2;}

class Solution {
public:
    int longestCommonSubpath(int n, vector<vector<int>>& paths) {
        int m=paths.size();
        b[0]=1; rep(i,1,maxn-5) b[i]=(b[i-1]*base)%mod; p.clear();
        b2[0]=1; rep(i,1,maxn-5) b2[i]=(b2[i-1]*base2)%mod2;
        int l=0,r=maxn,ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1,F=0; map <pair<ll,ll>,int> q;
            for(int i=0;i<m;i++)
            {
                for(int j=0;j<paths[i].size();j++)
                    h[j+1]=(h[j]*base+paths[i][j])%mod,h2[j+1]=(h2[j]*base2+paths[i][j])%mod2;
                rep(j,1,paths[i].size())
                {
                    if(j+mid-1>paths[i].size()) break;
                    ll tmp=gh(j,j+mid-1),tmp2=gh2(j,j+mid-1);
                    pair <ll,ll> qq=make_pair(tmp,tmp2);
                    if(!q[qq]) q[qq]=1,p[qq]++;
                    if(p[qq]==m) F=1;
                }
                q.clear();
            }
            if(F) ans=mid,l=mid+1; else r=mid-1;
            p.clear();
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值