LeetCode44双周赛

5645.找到最高海拔

模拟

class Solution {
public:
    int largestAltitude(vector<int>& gain) {
		int n=gain.size();
        int res=0;
        int t=0;
        for(int i=0;i<n;i++){
            t+=gain[i];
            res=max(res,t);
        }
        return res;
    }
};

1733.需要教语言的最少人数

哈希表+枚举

这个题当时做的时候理解错了题意,题目要求的是只能教一门语言,然后得到的最少人数,而我理解成了可以教多门语言,所以一直得不到正确的结果,屮!

class Solution {
public:
    int minimumTeachings(int n, vector<vector<int>>& lan, vector<vector<int>>& fri) {
        int m=lan.size();
        //用一个二维数组来存放每个人会的语言
        vector<vector<bool>> mp(505,vector<bool>(505,false));	
        for(int i=0;i<m;i++)
            for(auto l : lan[i])
                mp[i+1][l]=true;
        //然后遍历friends数组,找出哪些对朋友需要教语言。
        vector<vector<int>> nf;
        for(auto &f : fri){
            bool flag=false;
            int l=f[0],r=f[1];
            for(int i=1 ;i<=n && !flag ;i++){
                if(mp[l][i] && mp[r][i]) flag=true;
            }
            if(!flag) nf.push_back(f);
        }
        //遍历所有语言,然后每个语言下遍历那些需要教的朋友,如果这个人不会,那究t++,最后选需要教最少的!
        int res=m;	//答案初始化为m,也就是每对朋友都要教。
        for(int i=1;i<=n;i++){
            int t=0;
            for(auto & f : nf){
                int l=f[0],r=f[1];
                if(!mp[l][i]) ++t,mp[l][i]=true;
                if(!mp[r][i]) ++t,mp[r][i]=true;
            }
            res=min(res,t);
        }
        return res;
    }
};

5647.解码异或后的排列

异或性质

a^a = 0 a^0 = a a^b = c -> a^c = b

a1 ^ a2 ^ a3 … ^an = 1 ^ 2 ^3 …^n

题目中encoded 是 a1 ^ a2 , a2 ^ a3 , a3 ^ a4 … an-1 ^ an

所有我们取encoded中的偶数项进行全部异或,则得到

​ a2 ^ a3 ^ a4 ^ a5 …^an-1 ^ an , 那么再拿到刚才从1到n的异或结果,可以看出

a1 ^ a2 ^ a3 ^ a4 ^ a5 …^an-1 ^ an, 两者异或后结果为a1,因为相同的数异或结果为0,任何数异或0为其本身.

那么就知道了a1,那么原来的perm数组则可由 a1一直迭代求得。

class Solution {
public:
    vector<int> decode(vector<int>& encoded) {
        int n=encoded.size()+1;
        int A=0;
        for(int i=1;i<=n;i++)
            A^=i;
        
        int B=0;
        for(int i=1;i<encoded.size();i+=2)
            B^=encoded[i];
        
        int a1 = A^B;
        
        vector<int>res{a1};
        for(int i=0;i<encoded.size();i++){
            int t=res[i] ^ encoded[i];
            res.push_back(t);
        }
        return res;
    }
};

5648.生成乘积数组的方案数

组合隔板法+分解质因数

分解质因数,然后其中得到的各个因数是独立的,可以求出每个因数的方案数,然后相乘,就是最后的方案数。

那么问题就是我们怎么去抉择每个地方放什么,这就像将k个小球放进n+k个不同的篮子里,答案就是(n-1,n+k-1)种,所以预先处理组合数。

using LL = long long;
class Solution {
private:
    static constexpr int mod = 1e9+7;
    static constexpr int nmax =10000;
    static constexpr int logkmax = 13;
    static int c[nmax + longkmax][logkmax + 1];
    static bool inited;
    
    vector<int>factors;
    int n,k;
    int sum;
    int u;
public:
    //预处理组合数
    void init(){
        if(inited){
            return;
        }
        inited  =true;
        
        c[0][0]=1;
        for(int i=1;i<nmax+logkmax;i++){
            c[i][0]=1;
            for(int j=1;j<=i&&j<=logkmax;j++){
                c[i][j] = c[i-1][j-1]+c[i-1][j];
                if(c[i][j]>=mod)
                    c[i][j]-=mod;
            }
        }
    }

    vector<int> waysToFillArray(vector<vector<int>>& queries) {
        init();
        vector<int>res;
       	for(const auto& q :queries){
            int n=q[0],k=q[1];
            int sum=1;
            for(int i=2;i*i<=k;i++){
                if(k%i==0){
                    int y=0;
                    while(k%i==0){
                        ++y;
                        k/=i;
                    }
                    sum=(LL)sum*c[n+y-1][y] % mod;
                }
            }
            if(k>1){  //如果最后k仍是一个大的质数无法被分解,则可以将它放在任何一个地方,即sum*n
                sum = (LL)sum*n %mod;
            }
            res.push_back(sum);
        }
        return res;
    }
};
int Solution::c[nmax + logkmax][logkmax + 1] = {0};
bool Solution::inited = false;

你可能感兴趣的:(数据结构,算法,leetcode)