Coding Practice,48天强训(22)

Topic 1:添加字符

添加字符_牛客笔试题_牛客网

只允许头尾插入,也就是说只需要找到A在B中最匹配的位置,头尾插入的其实不用管,可以视作插和B一样的字符即可,所以找到A在B中最匹配的位置就等于找到了最少的不相等位数;

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    string A, B;
    cin >> A >> B;
    int res = INT_MAX, nA = A.length(), nB = B.length();   
    for(int i = 0; i <= nB - nA; ++i)
    {
        int tmp = 0;
        for(int j = 0; j < nA; ++j)
        {
            if(A[j] != B[i + j]) tmp++;
        }
        res = min(res, tmp);
    }
    cout << res << endl;
}

简单题简单做,没啥难度

Topic 2:数组变化

数组变换__牛客网

隐约感觉这题做过,分析一下,发现是在考察指数幂的问题,将一个数自由的(n次)乘两倍,其实就可以视作是2^n倍,那么我们也可以通过/2的操作把所有的数字还原到最小单位来进行比较,如果最后还原的最小单位都相等,也就意味着这些数字都是可以通过*2的操作,在某一时刻同时相等的,只是次数的不同而已;

比如两个数2 8,8可以视作2^3——1 * 2 * 2 * 2                     2可以视作1 * 2

在拥有无限*2操作权限的某一个时刻,这个2可以视作一个8,将两数不断/2,直到某个时刻,没办法再整除为止,也就是奇数时,比如8 2两个数不断/2,最后都被还原成1,对于这个1而言,只有后面跟着*2的次数不同,所以这两个数符合条件;

再比如两个数6,8,不断/2直至不能整除,6还原成3,3不能整除2,停止;8最后还原成1,3 != 1,所以6和8不符合条件

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    int n;
    cin >> n;
    vector<int> v(n);
    bool res = true;
    for(int i = 0; i < n; ++i)
    {
        cin >> v[i];
        while(!(v[i] % 2)) v[i] /= 2;
        if(v[i] != v[0])
        {
            res = false;
            break;
        }
    }
    cout << (res ? "YES" : "NO") << endl;
}

思路清晰代码就简单;还有一种方法,位运算的方法

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    int n;
    cin >> n;
    vector<int> v(n);
    bool res = true;
    for (int i = 0; i < n; ++i) 
    {
        cin >> v[i];
        // 用位运算替代 %2 和 /2
        while ((v[i] & 1) == 0) v[i] >>= 1;
        if (v[i] != v[0]) 
        {
            res = false;
            break;
        }
    }
    cout << (res ? "YES" : "NO") << endl;
    return 0;
}

Topic 3:装箱问题

装箱问题_牛客题霸_牛客网

01年的真题,20多年了,一个01背包的退阶问题,只用考虑重量,用动态规划来解

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int v, n; // v:箱子容量,n:物品数量
    cin >> v >> n;

    vector<int> grid(n); // grid[i] 表示第 i 件物品的体积
    for(int i = 0; i < n; ++i) cin >> grid[i];

    // dp[j] 表示:在容量为 j 的情况下,能装入的最大体积
    // 初始化为 0,因为什么都不装时最大体积是 0
    vector<int> dp(v + 1, 0);//v + 1,因为下标从0开始,v + 1能表示重量v的装载体积

    for(int i = 0; i < n; ++i)// 遍历每一件物品
    {
        for(int j = v; j >= grid[i]; --j)// 逆序遍历容量,从大到小,确保每件物品只能被使用一次(0/1 背包)
        {
            // 如果当前容量 j 能装下这件物品,就比较是否装上更优
            // 两种选择:不选这件物品(dp[j]),或选(dp[j - grid[i]] + grid[i])
            dp[j] = max(dp[j], dp[j - grid[i]] + grid[i]);
        }
    }

    // 箱子剩余空间 = 原始容量 v - 实际装进去的最大体积
    int res = v - dp[v];

    cout << res << endl;

    return 0;
}

这题没特别熟悉,之后有时间复习整个背包板块再来做一遍;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值