B4392 [常州市赛 2025] 压缩 贪心/答案根/位置关系
解题思路
这道题要求实现一个最优的"别重复"压缩算法,处理带通配符的二进制字符串。核心思想是通过为通配符赋值(0或1),使得应用压缩算法后得到最短的字符串。
关键观察
-
压缩本质:算法会删除连续重复的子串,最优策略是选择能使最终字符串最短的删除顺序
-
通配符处理:我们需要为通配符赋值,使得压缩后的字符串最短
-
模式识别:通过分析输入输出样例,可以发现一些规律:
-
如果字符串中同时包含0和1,结果通常是"10"、"01"、"101"或"010"
-
如果只有0或只有1,结果就是单个字符"0"或"1"
-
算法策略
代码中的solve函数采用了一种启发式方法:
-
统计字符串中0和1的数量
-
根据0和1的存在情况以及首尾字符的特性,决定最优的压缩结果
-
主要考虑四种情况,对应不同的二进制模式
代码注释
#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; }

浙公网安备 33010602011771号