牛客编程巅峰赛S1赛季第1场 - 青铜&白银局

文章目录

  • 牛客编程巅峰赛S1赛季第1场 - 青铜&白银局
    • A - 移动数字
      • 思路
      • 代码
    • B - 魔法数字
      • 思路
      • 代码
    • C - 牛妹的春游
      • 思路
      • 代码
    • 总结

牛客编程巅峰赛S1赛季第1场 - 青铜&白银局

比赛链接

牛客网新办的编程系列线上赛,主要面向求职者,所以提交的方式接近LeetCode。

A - 移动数字

思路

硬要说写法有很多种,不过最省事不需要怎么思考的还是扫描一遍串,统计一下’a’的个数,把非’a’的扔进返回串里,最后在返回串末尾补上相应个数个’a’.

代码

//
// Created by Visors on 2020/7/10.
//

#include 
#include 

using namespace std;

class Solution {
public:
    /**
     *
     * @param s string字符串
     * @return string字符串
     */
    string change(string s) {
        // write code here
        int tot = 0;
        string ret;
        for (auto it:s) {
            if (it == 'a') tot++;
            else ret.push_back(it);
        }
        while (tot--) ret.push_back('a');
        return ret;
    }
} run;

int main() {
    cout << run.change("abcavv") << endl;
    return 0;
}

B - 魔法数字

思路

这题一看就让我想起了奇怪的电梯那道题目,所以应该是BFS,不过我当时像个沙雕一样拿stack写了半天BFS,发现问题后调完都快结束了,交上去竟然只对了部分,实在不解……

显然当 n ≥ m n\geq m nm的时候,只能通过减1来从 n n n得到 m m m。在剩下的时间内,做加和乘时若 n ≥ m n\geq m nm显然不会拓展出最优解,同时减不能将 n n n减为负数。搜索时最好做一些记忆化操作优化搜索树宽度。

这份代码参考了榜一的写法,将计算结果作为循环终点挺有意思的。如果嫌弃函数里面开这么大的数组,使用map代替也是没问题的。

代码

//
// Created by Visors on 2020/7/10.
//

#include 
#include 
#include 

using namespace std;

class Solution {
public:
    /**
     * 返回最后要输出的答案
     * @param n int整型 表示牛牛的数字
     * @param m int整型 表示牛妹的数字
     * @return int整型
     */
    int solve(int n, int m) {
        // write code here
        if (n >= m) return n - m;
        int ans[1000005];
        queue<int> q;
        memset(ans, 0x3f, sizeof(ans));
        ans[n] = 0;
        q.push(n);
        while (ans[m] == 0x3f3f3f3f) {
            int temp = q.front();
            q.pop();
            if(temp<m){
                if(ans[temp+1]==0x3f3f3f3f) {
                    ans[temp+1]=ans[temp]+1;
                    q.push(temp+1);
                }
                if(ans[temp*temp]==0x3f3f3f3f) {
                    ans[temp*temp]=ans[temp]+1;
                    q.push(temp*temp);
                }
            }
            if(temp>1&&ans[temp-1]==0x3f3f3f3f){
                ans[temp-1]=ans[temp]+1;
                q.push(temp-1);
            }
        }
        return ans[m];
    }
}run;

int main(){
    cout<<run.solve(3,10)<<endl;
    return 0;
}

C - 牛妹的春游

思路

二维01背包,由于需求可以被过量满足,所以稍微改进一下状态转移方程,让下标减为负数时置零即可。

吐槽一下,虽然不给在线测试选手是可以进行本地测试,但是对于数据过大的样例,选手还是很难受的= =

代码

//
// Created by Visors on 2020/7/10.
//

#include 
#include 
#include 

using namespace std;

class Solution {
public:
    /**
     *
     * @param breadNum int整型
     * @param beverageNum int整型
     * @param packageSum int整型vector> 每个一维数组中有三个数,依次表示这个包装里面的面包数量、饮料数量、花费
     * @return int整型
     */
    int ans[2005][2005];

    int minCost(int breadNum, int beverageNum, vector<vector<int> > &packageSum) {
        // write code here
        memset(ans, 0x3f, sizeof(ans));
        ans[0][0] = 0;
        for (auto &package: packageSum) {
            int u = package[0], v = package[1], w = package[2];
            for (int i = breadNum; i >= 0; i--)
                for (int j = beverageNum; j >= 0; j--)
                    ans[i][j] = min(ans[i][j], ans[max(i - u, 0)][max(j - v, 0)] + w); // max(余量, 0)处理需求过量的情况
        }
        return ans[breadNum][beverageNum];
    }
} run;

int main() {
    vector<vector<int> > v(5);
    v[0].push_back(3);
    v[0].push_back(36);
    v[0].push_back(120);
    v[1].push_back(10);
    v[1].push_back(25);
    v[1].push_back(129);
    v[2].push_back(5);
    v[2].push_back(50);
    v[2].push_back(250);
    v[3].push_back(1);
    v[3].push_back(45);
    v[3].push_back(130);
    v[4].push_back(4);
    v[4].push_back(20);
    v[4].push_back(119);
    cout << run.minCost(5, 60, v) << endl;
}

总结

第一次打这种比赛,感觉状态有点迷。一开始蜜汁自信直接在在线编辑器敲,然后发现没有在线测试,直接开始肉眼debug,本地都没去调试,属实憨批,piapiapia。

你可能感兴趣的:(牛客,acm,解题报告)