洛谷:P7076
OJ:CSPS2020B
问题描述简要回顾:
算法思路:
existingBits
。(p_j, q_j)
:
freeBits
减 1。 freeBits
,则可能的动物编号组合数为 2freeBits。totalCombinations - n
。unsigned long long
的范围,需要特殊处理。变量声明:
n
:已有的动物数量。m
:饲养指南的要求数量。c
:饲料种类数量(在本程序中未直接使用)。k
:动物编号的二进制位数。freeBits
:可自由变化的位数,初始为 k
。bitMustBeZero[MAX_BITS]
:用于标记哪些位必须为 0。animalID
:动物编号。bitPosition
:饲养指南中的位位置 pjp_jpj。feedType
:饲养指南中的饲料种类 qjq_jqj。totalCombinations
:可能的动物编号组合数,初始为 1。existingBits
:已有动物编号的按位或结果。处理饲养指南:
bitPosition
和饲料种类 feedType
。(existingBits >> bitPosition) & 1
:检查 existingBits
的第 bitPosition
位是否为 1。!((existingBits >> bitPosition) & 1)
:如果结果为真,表示该位为 0。!bitMustBeZero[bitPosition]
:该位尚未被标记为必须为 0。freeBits
减 1,表示可自由变化的位数减少。bitMustBeZero[bitPosition]
标记为 true
。for (int i = 0; i < m; i++) { cin >> bitPosition >> feedType; if (!((existingBits >> bitPosition) & 1) && !bitMustBeZero[bitPosition]) { // 如果已有动物在第 bitPosition 位为 0,且该位尚未被标记为必须为 0 freeBits--; // 可自由变化的位数减 1 bitMustBeZero[bitPosition] = true; // 标记该位必须为 0 } }
算法复杂度分析:
bitMustBeZero
。代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /**************************************************************** * Description: 2020年提高组复赛第二题 动物园 * Author: Alex Li * Date: 2024-09-30 00:54:57 * LastEditTime: 2024-09-30 16:33:57 ****************************************************************/ #include <cstdio> #include <iostream> #define LL long long #define ULL unsigned long long const int MAX_BITS = 65; using namespace std; int n, m, c, k, freeBits; bool bitMustBeZero[MAX_BITS]; LL animalID, bitPosition, feedType; ULL totalCombinations = 1, existingBits; int main() { // freopen("zoo.in","r","stdin"); //freopen("zoo.in","w","stdout"); // 读取已有的动物数量 n,要求数量 m,饲料种类数量 c,动物编号的位数 k cin >> n >> m >> c >> k; freeBits = k; // 初始化可自由变化的位数为 k if (!n && !m && k == 64) { // 特殊情况处理:当没有已有动物和要求,且编号位数为 64 时 cout << "18446744073709551616"; return 0; } // 读取已有动物的编号,并计算所有编号的按位或结果 for (int i = 1; i <= n; i++) { cin >> animalID; existingBits |= animalID; // 将编号进行按位或,得到已有动物编号中为 1 的位 } // 处理饲养指南的要求 for (int i = 0; i < m; i++) { cin >> bitPosition >> feedType; if (!((existingBits >> bitPosition) & 1) && !bitMustBeZero[bitPosition]) { // 如果已有动物在第 bitPosition 位为 0,且该位尚未被标记为必须为 0 freeBits--; // 可自由变化的位数减 1 bitMustBeZero[bitPosition] = true; // 标记该位必须为 0 } } // 计算可能的动物编号组合数 for (int i = 1; i <= freeBits; i++) { totalCombinations *= 2; // totalCombinations = 2^freeBits } // 输出结果,减去已有的动物数量 cout << totalCombinations - n; return 0; } |