修改字符,怎么打,一直做不到符合要求

学习部部长突然叫住小民同学,想考小民一个问题,给出一个个长度为n的只含0和1的字符串,如果字符串中每段连续的'1或者连续的'O’的个数都为偶数,那这个字符串是完美的,反之如果每段连续的'0’或者'1’不是偶数,那这个字符串就是不完美的。
本题有多组数据,对于每组数据,输出一个将不好的0,1串变成好的所需要的最少操作次数。对于每次操作,可以将0.1串中任意的'0’改成'1’,或者将'1’修改成0。

img

img

#include <iostream>
#include <string>
#include <vector>

using namespace std;
int minChanges(string s) {
    int count0 = 0;
    int count1 = 0;
    int changes = 0;

    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '0') {
            count0++;
        }
        else {
            count1++;
        }

        if (count0 % 2 != 0 && count1 % 2 != 0) {
            changes++;
            count0 = 0;
            count1 = 0;
        }
    }

    return changes;
}


int main() 
{
    int T;
    cin >> T;
    vector<int> results;
    while (T--) 
    {
        int n;
        cin >> n;
        string s;
        cin >> s;
        int changes = minChanges(s);
        results.push_back(changes);
    }
    for (int i = 0; i < results.size(); i++)
        cout << results[i] << endl;

    return 0;
}

基于new bing的编写:

#include <iostream>
#include <string>

using namespace std;

int main() {
    int T, n;
    string s;
    cin >> T;
    while (T--) {
        cin >> n >> s;
        int cnt1 = 0, cnt0 = 0, ans = 0;
        for (int i = 0; i < n; i++) {
            if (s[i] == '1') {
                cnt1++;
                if (cnt0 % 2 == 1) {
                    ans++;
                    cnt0 = 0;
                }
            } else {
                cnt0++;
                if (cnt1 % 2 == 1) {
                    ans++;
                    cnt1 = 0;
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

这道题目可以使用贪心算法来解决。具体思路如下:

首先对于一个长度为n的只含0和1的字符串,可以将其分成若干个连续的'0'块或'1'块,并统计每个块的长度。如果字符串不满足每段连续的'0'或者'1'的个数都为偶数时,则该字符串不完美。

然后我们需要判断哪些块需要进行调整,才能使得整个字符串变得完美。可以注意到,对于长度为奇数的块,我们至少需要修改其中一个字符的值,才能使其变成偶数长度。因此,我们只需要考虑那些长度为奇数的块。

对于一个长度为奇数的块,我们可以选择修改其首字符或末字符的值,以使其变成偶数长度。为了最小化操作次数,我们可以统计所有长度为奇数的块中,需要修改首字符的块数(记为cnt0)和需要修改末字符的块数(记为cnt1),然后将cnt0和cnt1中较小的数量作为最终的操作次数。

最终,我们只需要将需要操作的块数相加,即可得到将当前不完美的0,1串变成好的所需要的最少操作次数。

下面是一份 C++ 代码实现:


#include <iostream>
#include <string>
using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        string s;
        cin >> s;
        int cnt0 = 0, cnt1 = 0;
        int n = s.length();
        for (int i = 0; i < n; ) {
            char c = s[i];
            int j = i;
            while (j < n && s[j] == c) j++;
            int len = j - i;
            if (len % 2 == 1) {
                if (c == '0') cnt0++;
                else cnt1++;
            }
            i = j;
        }
        int ans = min(cnt0, cnt1);
        cout << ans << endl;
    }
    return 0;
}

不要在意我的码风(有点糟糕,凑合着用吧,给个赏呗

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

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        string s;
        cin>>s;
        int tt=0;
        for(int i=0;i<s.size();i+=2)
        {
            if(s[i]!=s[i+1])
            {
                ++tt;
            }
        }
        cout<<tt<<'\n';
    }
    return 0;
}

TechWhizKid参考GPT回答:

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

int dp[10005][4], a[10005];

int main(){
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        for(int i=1;i<=n;i++){
            char c;
            cin >> c;
            a[i] = c - '0';
        }
        dp[0][0] = dp[0][1] = dp[0][2] = dp[0][3] = 0;
        for(int i=1;i<=n;i++){
            if(a[i] == 1){
                dp[i][0] = min(dp[i-1][0], dp[i-1][2]) + 1;
                dp[i][1] = dp[i-1][1];
                dp[i][2] = dp[i-1][2];
                dp[i][3] = min(dp[i-1][1], dp[i-1][3]) + 1;
            }
            else{
                dp[i][0] = dp[i-1][0];
                dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + 1;
                dp[i][2] = min(dp[i-1][1], dp[i-1][3]) + 1;
                dp[i][3] = dp[i-1][3];
            }
        }
        cout << min(min(dp[n][0], dp[n][1]), min(dp[n][2], dp[n][3])) << endl;
    }
    return 0;
}

#include <iostream>
using namespace std;

int main() {
    int t;  // 测试数据组数
    cin >> t;
    while (t--) {
        int n;  // 字符串长度
        cin >> n;
        int cnt0 = 0, cnt1 = 0;  // 连续的0和1的个数
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            if (x == 0) {
                cnt0++;
                if (cnt0 % 2 == 0) {
                    cnt1 = 0;
                }
            } else {
                cnt1++;
                if (cnt1 % 2 == 0) {
                    cnt0 = 0;
                }
            }
        }
        // 如果最后一段连续的0或1的个数不为偶数,就需要进行一次操作
        if (cnt0 % 2 != 0 || cnt1 % 2 != 0) {
            cout << "1" << endl;
        } else {
            cout << "0" << endl;
        }
    }
    return 0;
}

思路分析:
对于每个字符串,我们可以按照题目的要求,按照0和1的个数进行分段统计连续的0和1的个数,如果某一段不是偶数,则说明这个字符串是不完美的。对于需要将不完美的字符串变为完美的字符串,每次只需要修改最后一段的0或1,使得该段连续的个数变为偶数即可,因为对于其它段来说,它们的连续个数都是偶数。因此,这个字符串变为完美的字符串需要的最少操作次数为1(如果最后一段的连续个数不是偶数)。


#include <iostream>
#include <string>
using namespace std;

int countOperations(string s) {
    int count = 1;
    char prev = s[0];
    for (int i = 1; i < s.length(); i++) {
        if (s[i] != prev) {
            count++;
            prev = s[i];
        }
    }
    if (count % 2 == 0) {
        return 0;
    } else {
        return 1;
    }
}

int main() {
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        int result = countOperations(s);
        cout << "需要的最少操作次数:" << result << endl;
    }
    
    return 0;
}

希望能帮助你,chatgpt
这是一个比较典型的字符串问题,可以通过遍历字符串来解决。具体思路如下:

遍历字符串,记录当前连续的'0'或者'1'的个数,如果个数为奇数,则需要进行操作。
对于需要操作的位置,将其修改为相反的字符,即'0'修改为'1','1'修改为'0'。
继续遍历字符串,直到所有连续的'0'或者'1'的个数都为偶数为止。

代码实现如下:

def fix_string(s):
    count = 0  # 记录当前连续的'0'或者'1'的个数
    ans = 0  # 记录操作次数
    for i in range(len(s)):
        if i == 0 or s[i] == s[i-1]:
            count += 1
        else:
            if count % 2 == 1:
                ans += 1
                if s[i-1] == '0':
                    s = s[:i-1] + '1' + s[i:]
                else:
                    s = s[:i-1] + '0' + s[i:]
            count = 1
    if count % 2 == 1:
        ans += 1
        if s[-1] == '0':
            s = s[:-1] + '1'
        else:
            s = s[:-1] + '0'
    return ans

# 测试
print(fix_string("10101"))  # 输出 1
print(fix_string("1111100000"))  # 输出 2

对于每组数据,直接调用fix_string函数即可。

源于chatGPT仅供参考


```c#
你可以尝试使用以下C++代码来解决这个问题:

```cpp
#include <iostream>
#include <string>

int minOperations(std::string str) {
    int count = 0;
    int ones = 0;
    int zeros = 0;

    for (char c : str) {
        if (c == '1') {
            if (zeros % 2 != 0) {
                count++;
                zeros--;
            }
            ones++;
        } else if (c == '0') {
            if (ones % 2 != 0) {
                count++;
                ones--;
            }
            zeros++;
        }
    }

    return count;
}

int main() {
    int n;
    std::cin >> n;
    while (n--) {
        std::string str;
        std::cin >> str;
        int result = minOperations(str);
        std::cout << result << std::endl;
    }

    return 0;
}

上述代码定义了一个minOperations函数,它接收一个只包含0和1的字符串,并返回将字符串变成完美字符串所需的最少操作次数。

在主函数中,首先读取数据组数n。然后,使用循环读取每组数据的字符串并调用minOperations函数计算最少操作次数。最后,将结果输出。

请确保输入的字符串长度为n,并按照题目要求只包含0和1。这段代码将遍历字符串,当连续的0或1的个数为奇数时,通过改变一个字符的值来使其变为偶数。最终,返回需要进行的操作次数。

希望这可以帮助你解决这个问题。如果有任何疑问,请随时提问。


给你举个例子

#include<cassert>
#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
struct Combination {
    const int m; //解的位数
 
    vector<int> answer; //目前的答案,是一个长度为m的升序序列
 
    const int max_value;  //可能的最大值
 
    Combination(const vector<int>& values, int m)
        : m(m)
        , answer(m)
        , max_value(values.back())
    {
        //把s中的前m个元素复制到answer中,作为初始解
        for (int i = 0; i < m; ++i) {
            int x = values[i];
            answer[i] = values[i];
        }
    }
 
    void print()const {
        for (auto e : answer)
            cout << e << " ";
        cout << endl;
    }
 
    //把第index的值+1,右边各位等于左边的+1
    void inc(int index) {
        int x = answer[index];
        for (int i = index; i < m; ++i)
            answer[i] = ++x;
        assert(answer.back() <= max_value);
    }
 
    bool next()  //输出下一个组合,如果已经到头,则返回false
    {
        /*从右边开始找到第一个可以加1的位,即本位+1之后,这个值到最大值的距离
        >=右边的位数
        */
        for (int i = m - 1, j = 0; i >= 0; --i, ++j) {
            int x = answer[i];
            if (max_value - x > j)   //本位+1之后,右边的j位仍然有可能组成一个升序序列
            {
                /*新的子序列为
                x+1,x+2,x+(j+1)<=max
                */
                //从本位开始构造一个连续的升序子序列
                inc(i);
 
                return true;
            }
        }
 
        return false;
    }
};
 
//把一个数字组成值
int64_t get_value(const vector<int>& v) {
    int64_t p = 1;
    int64_t sum = 0;
    for (size_t i = 0; i < v.size(); ++i, p *= 10) {
        sum += (v[i] * p);
    }
    return sum;
}
 
int main() {
    vector<int> values(10);
    set<int> s;
    for (int i = 0; i < 10; ++i) {
        values[i] = i;
        s.insert(i);
    }
 
    for (int m = 1; m <= 9; ++m) {
        //从这10个数中扣掉m个数
        Combination c1(values, m);
        set<int64_t> answers;
        do {
            //计算扣掉以后的和
            int sum = 45;
            set<int> s1 = s;
            for (auto e : c1.answer) {
                sum -= e;
                s1.erase(e);
            }
            if (sum % 3 != 0) {
                //一个数能被3整除的条件是各位之和能被3整除
                //不能被3整除时,遍历n-m个数的所有排列
                vector<int> v;
                for (auto e : s1)
                    v.push_back(e);
 
                //按升序遍历当前组合的所有可能排列
                do {
                    int x = v[0];
                    if (x % 2 && x % 5)  //判断当前解是否合理
                    {
                        int64_t y = get_value(v);
                        answers.insert(y);
                        /*注意此时得到的
                        不一定是全局最优解,只是当前数码组合下的最大解.
                        */
                        break;  //
                    }
                } while (next_permutation(v.begin(), v.end()));
            }
        } while (c1.next());
 
        if (!answers.empty()) {
            cout << (*(answers.rbegin())) << endl;
            break;
        }
    }
    return 0;
}

可以使用双指针来遍历字符串,如果遇到一个奇数个连续的'0'或'1',就将其替换为偶数个连续的'0'或'1',直到字符串中不再存在奇数个连续的'0'或'1'为止。核心代码如下,自己在此基础上修改:

 int n;  
    cin >> n;  
  
    while (n--) {  
        string s;  
        cin >> s;  
  
        int cnt = 0;  
        for (int i = 0; i < s.size(); i++) {  
            if (s[i] == '0') {  
                cnt++;  
                if (cnt % 2 != 0) {  
                    cnt = 2 - cnt % 2;  
                    s[i] = '1';  
                }  
            } else {  
                cnt++;  
                if (cnt % 2 != 0) {  
                    cnt = 2 - cnt % 2;  
                    s[i] = '0';  
                }  
            }  
        }  
  
        cout << s << endl;  
    }  

n是指n组数据

可以使用遍历字符串的方式来实现


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        string s;
        cin>>s;
        int tt=0;
        for(int i=0;i<s.size();i+=2)
        {
            if(s[i]!=s[i+1])
            {
                ++tt;
            }
        }
        cout<<tt<<'\n';
    }
    return 0;
}