LeetCode 第20场双周赛 题解

传送门

A 根据数字二进制下的1的数目排序

题目大意

就是名字的字面意思
将数组中的元素按照其二进制表示中数字 1 的数目升序排序。如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。

解题思路

按题意模拟

代码

int cmp(vector<int> a, vector<int> b)
{
    return a[1]<b[1]||(a[1]==b[1]&&a[0]<b[0]);
}
class Solution {
public:
    int calc(int x)
    {
        int ans=0;
        while (x)
        {
            ans+=x&1;
            x>>=1;
        }
        return ans;
    }
    vector<int> sortByBits(vector<int>& arr) {
        vector<vector<int>> Sort;
        int n=arr.size();
        for (int i=0;i<n;++i)
        {
            vector<int> temp;
            temp.push_back(arr[i]);
            temp.push_back(calc(arr[i]));
            Sort.push_back(temp);
        }
        sort(Sort.begin(),Sort.end(),cmp);
        for (int i=0;i<n;++i)
            arr[i]=Sort[i][0];
        return arr;
    }
};

B 每隔 n 个顾客打折

题目大意

有一些顾客要买一些商品,商品的价格和数量给出,商家每隔n个顾客会打折,问每个人实际花销。

解题思路

按题意模拟。。

代码

class Cashier {
public:
    int N,Discount,cnt;
    vector<int> Products,Prices;
    int tot=0;
    Cashier(int n, int discount, vector<int>& products, vector<int>& prices) {
        N=n;
        Discount=discount;
        Products=products;
        Prices=prices;
        cnt=products.size();
    }
    
    double getBill(vector<int> product, vector<int> amount) {
        int n=product.size();
        double p=0;
        ++tot;
        for (int i=0;i<n;++i)
        {
            for (int j=0;j<cnt;++j)
                if (Products[j]==product[i])
                {
                    p+=(double)Prices[j]*(double)amount[i];
                    break;
                }
        }
        if (tot%N==0)
            p=p-((double)Discount*p)/100.0;
        return p;
    }
};

/**
 * Your Cashier object will be instantiated and called as such:
 * Cashier* obj = new Cashier(n, discount, products, prices);
 * double param_1 = obj->getBill(product,amount);
 */

C 包含所有三种字符的子字符串数目

题目大意

给出一个字符串,求包含了三种字符的子字符串数目。

解题思路

双指针,左指针枚举子串的开头,右指针指向符合要求的最短子串结尾(子串结尾在右指针之右的肯定都成立,直接计算),显然两指针单调。

代码

class Solution {
public:
    int numberOfSubstrings(string s) {
        int n=s.length();
        int l=0,r=0,ans=0;
        int a=0,b=0,c=0;
        if (s[0]=='a') ++a;
        else if (s[0]=='b') ++b;
        else ++c;
        while (l<n)
        {
            while (r<n-1&&(!a||!b||!c))
            {
                ++r;
                if (s[r]=='a') ++a;
                else if (s[r]=='b') ++b;
                else ++c;
            }
            if (a&&b&&c)
                ans+=n-r;
            if (s[l]=='a') --a;
            else if (s[l]=='b') --b;
            else --c;
            ++l;
        }
        return ans;
    }
};

D 有效的快递序列数目

题目大意

给出n个二元组,将其合并产生一个长度为2n的排列,其中二元组的内部顺序不能改变,求可能的排列个数。(给出的n个二元组互不相同)。

解题思路

数学题?不不,还是模拟。
一个一个的排,只不过用一个等差数列求和公式这也叫数学题

代码

class Solution {
public:
    int countOrders(int n) {
        if (n==1) return 1;
        int loc=1,ans=1,Mod=1000000007,now;
        for (int i=2;i<=n;++i)
        {
            loc+=2;
            now=(1+loc)*loc/2;
            ans=(int)(((long long)ans*(long long)now)%Mod);
        }
        return ans;
    }
};

你可能感兴趣的:(Contest)