牛客编程巅峰赛S1赛季第1场 - 青铜&白银局
牛客网新办的编程系列线上赛,主要面向求职者,所以提交的方式接近LeetCode。
A - 移动数字
思路
硬要说写法有很多种,不过最省事不需要怎么思考的还是扫描一遍串,统计一下’a’的个数,把非’a’的扔进返回串里,最后在返回串末尾补上相应个数个’a’.
代码
//
// Created by Visors on 2020/7/10.
//
#include <iostream>
#include <string>
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 n≥m的时候,只能通过减1来从 n n n得到 m m m。在剩下的时间内,做加和乘时若 n ≥ m n\geq m n≥m显然不会拓展出最优解,同时减不能将 n n n减为负数。搜索时最好做一些记忆化操作优化搜索树宽度。
这份代码参考了榜一的写法,将计算结果作为循环终点挺有意思的。如果嫌弃函数里面开这么大的数组,使用map代替也是没问题的。
代码
//
// Created by Visors on 2020/7/10.
//
#include <iostream>
#include <cstring>
#include <queue>
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 <iostream>
#include <vector>
#include <cstring>
using namespace std;
class Solution {
public:
/**
*
* @param breadNum int整型
* @param beverageNum int整型
* @param packageSum int整型vector<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。