1. 题目背景解析
P3005 [USACO10DEC] The Trough Game S 是美国计算机奥林匹克竞赛(USACO)2010年12月月赛的一道银组题目。这道题属于典型的状态空间搜索问题,考察选手对穷举算法和位运算优化的理解应用能力。
题目设定在一个农场场景中:农夫约翰和奶牛们玩一个猜谜游戏。游戏使用一个特殊的饲料槽装置,槽上有N个开关(1≤N≤20)和M个状态描述(1≤M≤100)。每个开关可以处于开(1)或关(0)状态,每个状态描述包含一个长度为N的二进制串和一个数字C,表示当开关组合与该二进制串匹配时,会有恰好C个指示灯亮起。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题建模与算法选择
2.1 问题抽象化
我们需要找到一个N位的二进制数X,使得对于所有M个约束条件:
- 对于第i个约束的条件二进制串S_i,计算X与S_i按位与的结果中1的个数(即popcount(X & S_i))
- 该结果必须等于约束中给定的C_i
2.2 算法分析
由于N的范围是1到20,可能的组合数是2^20=1,048,576,这在现代计算机的处理能力范围内,因此可以采用暴力枚举的方法:
- 生成所有可能的N位二进制数(从0到2^N-1)
- 对每个候选解,检查是否满足所有M个约束条件
- 统计符合要求的解的数量:
- 如果解的数量为0,输出"IMPOSSIBLE"
- 如果解的数量为1,输出该解
- 如果解数量>1,输出"NOT UNIQUE"
2.3 位运算优化
为了高效实现,需要使用位运算技巧:
- 使用整数表示二进制状态(int或long long类型)
- 通过左移运算(<<)构建掩码
- 使用按位与(&)计算约束条件
- 使用__builtin_popcount(GCC)或bitset的count()快速计算1的位数
3. 详细实现步骤
3.1 输入处理
首先需要处理输入数据:
- 第一行两个整数N和M
- 接下来M行,每行一个长度为N的字符串和一个整数C
建议存储约束条件为:
cpp复制vector<pair<int, int>> constraints; // {mask, count}
3.2 枚举所有可能性
使用一个循环枚举所有
