B4392 [常州市赛 2025] 压缩 贪心/答案根/位置关系

解题思路

这道题要求实现一个最优的"别重复"压缩算法,处理带通配符的二进制字符串。核心思想是通过为通配符赋值(0或1),使得应用压缩算法后得到最短的字符串。

关键观察

  1. 压缩本质:算法会删除连续重复的子串,最优策略是选择能使最终字符串最短的删除顺序

  2. 通配符处理:我们需要为通配符赋值,使得压缩后的字符串最短

  3. 模式识别:通过分析输入输出样例,可以发现一些规律:

    • 如果字符串中同时包含0和1,结果通常是"10"、"01"、"101"或"010"

    • 如果只有0或只有1,结果就是单个字符"0"或"1"

算法策略

代码中的solve函数采用了一种启发式方法:

  1. 统计字符串中0和1的数量

  2. 根据0和1的存在情况以及首尾字符的特性,决定最优的压缩结果

  3. 主要考虑四种情况,对应不同的二进制模式

代码注释

 

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 10,inf = 0x3f3f3f3f;

string solve(string s)
{
    int c1 = 0,c2 = 0;
    int n = s.size();
    for(int i = 0; i < s.size(); i++){
        if(s[i] == '1') c1++;  // 统计1的个数
        if(s[i] == '0') c2++;  // 统计0的个数
        // 如果同时存在0和1,且最后一个字符不是'1'且第一个字符不是'0',返回"10"
        if(c1 && c2 && s[n - 1] != '1' && s[0] != '0') return "10";
        // 如果同时存在0和1,且最后一个字符不是'0'且第一个字符不是'1',返回"01"
        else if(c1 && c2 && s[n - 1] != '0' && s[0] != '1')  return "01";
        // 如果同时存在0和1,且最后一个字符不是'0'且第一个字符不是'0',返回"101"
        else if(c1 && c2 && s[n - 1] != '0' && s[0] != '0') return "101";
        // 如果同时存在0和1,且最后一个字符不是'1'且第一个字符不是'1',返回"010"
        else if(c1 && c2 && s[n - 1] != '1' && s[0] != '1') return "010";
    }
    // 如果不满足以上条件(例如只有1或只有0),返回"1" or "0"
    if(c1) return "1";
    else return "0";
}

int main()
{
    string s; 
    cin >> s; 
    cout << solve(s) << endl; 
    return 0;
}

 

posted @ 2025-09-10 14:51  CRt0729  阅读(10)  评论(0)    收藏  举报