洛谷: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; } |