最近一期div2Bswap and delete

本文介绍了一种解决关于二进制字符串操作问题的贪心策略,通过计算1和0的前缀数量,确定最小成本使其满足特定条件,利用计数数组和取反操作简化问题求解。
摘要由CSDN通过智能技术生成

给你一个二进制字符串 s (一个只由 0-s 和 1-s 组成的字符串)。

您可以对 s 进行两种操作:

1. 从 s 中删除一个字符。该操作需要花费 1 个硬币;
2. 交换 s 中的任意一对字符。该操作是免费的(需要花费 0 个金币)。

您可以任意次数和顺序执行这些操作。

让我们将执行上述操作后得到的字符串命名为 t 。如果从**1 到 |t|的每个 i** t _ i \neq s _ i 都是字符串 t ,那么这个字符串 t 就是好字符串。 |t| 是字符串 t 的长度)。空字符串总是好字符串。请注意,您正在比较结果字符串 t 和初始字符串 s 。

使字符串 t 变好的最小总成本是多少?

这道题其实我第一眼看到很懵逼,后面也是看了一下别人的想法写出来的,其实本质上是一个贪心的问题,首先你要计算一下1和0的值,而且居于他原本t1不能等于s1相当于一个取反,因为存在交换和删除,如果1的数量等于0,那么消耗为零,否则就要进行另一方面考虑,那么这点其实就是一个难点,其实我开始也是这样想的,但是其实不用可以这样来,比如是111100,就先通过二维数组计算出1和0的个数,然后通过计算出1的数量为4,0为2,则使用cnt[1-(s[i]-'0')]判断当0的数字为0时,那么计算总长度也就是s.length()-i就是答案.还有额外的情况也就是0,就可以用i=s.length进行判断,上代码

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int calculatePrefixLength(const string& s) {

    vector<int> cnt(2, 0);

    for (int i = 0; i < s.length(); ++i) {

        cnt[s[i] - '0']++;//转换数字

    }

    for (int i = 0; i <= s.length(); ++i) {

        if (i == s.length() || cnt[1 - (s[i] - '0')] == 0) {

            return s.length() - i;

        }

        cnt[1 - (s[i] - '0')]--;

    }

    return 0;

}

int main() {

    int n;

    cin >> n;

    for (int i = 0; i < n; ++i) {

        string s;

        cin >> s;

        cout << calculatePrefixLength(s) << endl;

    }

    return 0;

}

int main() { size_t v7; char *i; int j; unsigned int v10; unsigned int v11; unsigned int v12; unsigned int v13; unsigned int *v14; int v15; unsigned int *v16; int k; unsigned int v19; unsigned int v20; unsigned int v21; unsigned int v22; char v23; unsigned char a3[] = "UK*@3oKpFlVVnadsTfdA"; unsigned char a1[] = "a1n"; unsigned char a2 = 3; unsigned int a4 = 20; unsigned char sbox0[2] = {0x63,0x7c}; unsigned char sbox1[2] = {0x63,0x7c}; unsigned char a5[2]={0x00, 0x30}; if ( !a5 || a2 <= 0 || !a3 || a4 <= 0 ) return -1; if ( a4 >= 16 ) v7 = 16; else v7 = a4; memcpy(&v19, a3, v7); for ( i = (char *)&v19 + v7; i != &v23; ++i ) *i = sbox1[(unsigned __int8)*(i - 1)]; for ( j = 0; j != 16; ++j ) *((_BYTE *)&v19 + j) = sbox0[*((unsigned __int8 *)&v19 + j)]; v10 = bswap32(v19); v19 = v10; v11 = bswap32(v20); v20 = v11; v12 = bswap32(v21); v21 = v12; v22 = bswap32(v22); v13 = v22; v14 = (unsigned int *)memmove((void *)(a5 + 6), a1, a2); *(_BYTE *)a5 = 116; *(_BYTE *)(a5 + 1) = 99; *(_BYTE *)(a5 + 2) = 3; *(_BYTE *)(a5 + 4) = 0; *(_BYTE *)(a5 + 5) = 1; v15 = 6; *(_BYTE *)(a5 + 3) = -(char)a2 & 0xF; v16 = v14; do { *(_BYTE *)(a5 + v15) = sbox0[*(unsigned __int8 *)(a5 + v15)]; ++v15; } while ( v15 < a2 + 6 + (-a2 & 0xF) ); for ( k = 0; k < (a2 + (-a2 & 0xF)) >> 4; ++k ) { *v16 = bswap32(bswap32(*v16) ^ v10); v16[1] = bswap32(v11 ^ __ROR4__(bswap32(v16[1]), 24)); v16[2] = bswap32(v12 ^ __ROR4__(bswap32(v16[2]), 16)); v16[3] = bswap32(v13 ^ __ROR4__(bswap32(v16[3]), 8)); v16 += 4; } return 0; }完善代码
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼di咖波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值