超级码力在线编程大赛初赛 第3场

   日期:2020-09-06     浏览:87    评论:0    
核心提示:A、最大公倍数是一个结论题吧。当 bbb 是奇数的时候,那么答案肯定是 b∗(b−1)∗(b−2)b*(b-1)*(b-2)b∗(b−1)∗(b−2),因为他们两两互质。然后当 b−a==2b-a==2b−a==2时,直接求一个lcm。否则就是偶数:偶数的话如果是3的倍数,答案就是(b−1)∗(b−2)∗(b−3)(b-1)*(b-2)*(b-3)(b−1)∗(b−2)∗(b−3),否则b-1,就变成奇数的情况了。class Solution {public: /** * @p

A、最大公倍数

是一个结论题吧。
b b b 是奇数的时候,那么答案肯定是 b ∗ ( b − 1 ) ∗ ( b − 2 ) b*(b-1)*(b-2) b(b1)(b2),因为他们两两互质。
然后当 b − a = = 2 b-a==2 ba==2时,直接求一个lcm。
否则就是偶数:偶数的话如果是3的倍数,答案就是 ( b − 1 ) ∗ ( b − 2 ) ∗ ( b − 3 ) (b-1)*(b-2)*(b-3) (b1)(b2)(b3),否则b-1,就变成奇数的情况了。

class Solution {
public:
    
    #define ll long long
    template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
    template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}
    else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
    ll greatestcommonmultiple(int a, int b) {
        // write your code here
        ll res = 0;
        if(b&1)res = 1ll*b*(b-1)*(b-2);
        else if(b-a==2){
            res = lcm(b,lcm(b-1,b-2));
        }else{
            if(b%3!=0)res = 1ll*b*(b-1)*(b-3);
            else res =  1ll*(b-1)*(b-2)*(b-3);
        }
        return res;
    }
    ll lcm(int a,int b){
        return 1ll*a*b/gcd(a,b);
    }
};

B、房屋染色

定义 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 表示以 i i i结尾颜色为 j j j且是否已有步行街的最小代价 ( 0 ≤ k ≤ 1 ) (0≤k≤1) (0k1)
然后维护一个前缀和,那么转移就是
只移动一步。
d p [ i + 1 ] [ k ] [ 0 ] = m i n ( d p [ i + 1 ] [ k ] [ 0 ] , d p [ i ] [ j ] [ 0 ] + c o s t s [ i + 1 ] [ k ] ) ; dp[i+1][k][0] = min(dp[i+1][k][0],dp[i][j][0]+costs[i+1][k]); dp[i+1][k][0]=min(dp[i+1][k][0],dp[i][j][0]+costs[i+1][k]);
d p [ i + 1 ] [ k ] [ 1 ] = m i n ( d p [ i + 1 ] [ k ] [ 1 ] , d p [ i ] [ j ] [ 1 ] + c o s t s [ i + 1 ] [ k ] ) ; dp[i+1][k][1] = min(dp[i+1][k][1],dp[i][j][1]+costs[i+1][k]); dp[i+1][k][1]=min(dp[i+1][k][1],dp[i][j][1]+costs[i+1][k]);
有步行街。
d p [ i + p ] [ k ] [ 1 ] = m i n ( d p [ i + p ] [ k ] [ 1 ] , d p [ i ] [ k ] [ 0 ] + v a [ i + p ] [ k ] − v a [ i ] [ k ] ) ; dp[i+p][k][1] = min(dp[i+p][k][1],dp[i][k][0]+va[i+p][k]-va[i][k]); dp[i+p][k][1]=min(dp[i+p][k][1],dp[i][k][0]+va[i+p][k]va[i][k]);

class Solution {
public:
    
    long long va[105][105];
    long long dp[105][105][2];
    int paintHouseIII(vector<vector<int>> &costs, int t) {
        // Write your code here.
        int n = costs.size(),m = costs[0].size();
        for(int i = 0;i < m;++i){
            for(int j = 0;j < n;++j){
                if(j==0)va[j][i] = costs[j][i];
                else va[j][i] = va[j-1][i] + costs[j][i];
               // cout<<j<<" "<<i<<" " << va[j][i]<<endl;
                dp[j][i][0] = dp[j][i][1] = INT_MAX;
            }
        }
        for(int i = 0;i < m;++i)dp[0][i][0] = dp[0][i][1] = costs[0][i];
        for(int i = 0;i < n;++i){
            for(int j = 0;j < m;++j){
                for(int k = 0;k < m;++k){
                    if(j==k){
                        for(int p = 0;p < t;++p){
                            if(i+p>=n)break;
                            dp[i+p][k][1] = min(dp[i+p][k][1],dp[i][k][0]+va[i+p][k]-va[i][k]);
                        }
                        continue;
                    }
                    if(i+1<n){
                        dp[i+1][k][0] = min(dp[i+1][k][0],dp[i][j][0]+costs[i+1][k]);
                        dp[i+1][k][1] = min(dp[i+1][k][1],dp[i][j][1]+costs[i+1][k]);
                    }
                }
            }
        }
        long long res = INT_MAX;
        for(int i = 0;i < m;++i)res = min(res,min(dp[n-1][i][1],dp[n-1][i][0]));
        return res;
    }
};

字符串游戏

抽象为 逆Nim 博弈
Nim 博弈:两个人玩游戏,有 n 堆石子,每次操作可以选一堆石子xjb拿,最少拿一颗,无子可取者为负。

class Solution {
public:
    
    bool stringGame(string &s) {
        // Write your code here.
        int num[30] = {0};
        for(int i = 0;i < s.size();++i){
            num[s[i]-'a']++;
        }
        int res = 0;
        bool f= 1,f1 = 0;
        for(int i = 0;i < 26;++i){
            if(!num[i])continue;
            res ^= num[i];
            if(num[i]!=1)f = 0;
            if(num[i]>1)f1 = 1;
        }
        if(f&&!res||f1&&res)return true;
        else return false;
    }
};

完美字符串

直接选取连续的0,然后最大限度的翻转它就ok了,即当有连续5个0,k=3,那么需要翻转2次。

class Solution {
public:
    
    int perfectString(string &s, int k) {
        long long res = 0;
        int i = 0,len,j;
        while(i < s.size()){
            if('1'==s[i]){i++;continue;}
            j = i;
            while(j<s.size()&&s[j]=='0')++j;
            len = j-i;
            res += len/k;
            if(len%k)res++;
            i = j;
        }
        return res;
    }
}a;
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服