1. 问题描述:

农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题。约翰给贝茜出了一道相当难的问题,导致她没能解决。现在,她希望通过给约翰出一道有挑战性的难题来报复他。贝茜给了约翰一个表达式 (B+E+S+S+I+E)(G+O+E+S)(M+O+O),其中包含七个变量 B,E,S,I,G,O,M(O 是变量,不是零)。对于每个变量,她给约翰一个列表,表中包含该变量可采用的最多 20 个整数值。她要求约翰计算,共有多少种给变量赋值的方法可以使得表达式的计算结果为偶数。

输入格式

第一行包含一个整数 N。接下来 N 行,每行包含一个变量和该变量的一个可能值。每个变量至少出现 1 次,最多出现 20 次。同一变量不会重复列出同一可能值。

输出格式

输出可以使得表达式的计算结果是偶数的给变量赋值的方法总数。

数据范围

7 ≤ N ≤ 140,

所有变量的可能取值范围 [−300,300],本题答案不会超出int范围。

输入样例:

10
B 2
E 5
S 7
I 10
O 16
M 19
B 3
G 1
I 9
M 2

输出样例:

6
样例解释
共有 6 种可能的赋值方式:
    (B,E,S,I,G,O,M) = (2, 5, 7, 10, 1, 16, 19) -> 53,244
                = (2, 5, 7, 10, 1, 16, 2 ) -> 35,496
                = (2, 5, 7, 9,  1, 16, 2 ) -> 34,510
                = (3, 5, 7, 10, 1, 16, 2 ) -> 36,482
                = (3, 5, 7, 9,  1, 16, 19) -> 53,244
                = (3, 5, 7, 9,  1, 16, 2 ) -> 35,496
注意,(2, 5, 7, 10, 1, 16, 19) 和 (3, 5, 7, 9, 1, 16, 19),虽然计算结果相同,但是赋值方式不同,所以要分别计数。
来源:https://www.acwing.com/problem/content/1877/

2. 思路分析:

首先我们需要想一下如何将题目先做出来再考虑如何优化,由题目可知每一种字母最多有20种取值,所以在最坏情况下的方案数目为20 ^ 7 = 128000000那么一定会超时的所以我们考虑如何对其进行优化,可以发现最终我们关注的是等式的奇偶性而不是等式最终的结果,题目中要求判断出对于某种选择方案最终的结果是奇数还是偶数等价于表达式的结果对于2取余的结果是多少,而取余的等式中是存在某些性质的,例如(a + b) % c = (a % c + b % c) % c也即可以分开求解,基于这个想法我们考虑所有的字母对于2取余的结果是奇数还是偶数的情况进行枚举,也即对于2取余的结果为0还是为1,所以只需要枚举字符串"BESIGOM"中每一个字母对于2取余的结果是奇数还是偶数的所有状态即可,也即枚举2 ^ 7种状态即可(枚举对应的十进制数字即可),并且在一开始的时候我们可以使用两个哈希表mp1和mp2分别记录出现奇数还是偶数次数的字母出现的次数,并且使用一个哈希表mp来记录当前枚举的状态中各个字母对于2的取余情况方便判断当前的等式结果对于2取余的结果是否是偶数,当满足条件之后那么累加对应的方案数目即可。并且表达式:(B+E+S+S+I+E)(G+O+E+S)(M+O+O)对于2取余的结果可以先化简一下(如果式子中出现了偶数次的字母那么对于2取余的结果为0所以对于结果没有什么影响直接忽略掉),为:(B + I) * (G + O + E + S) * M,对于某个状态是0还是1的一般可以使用dfs(dfs递归两个平行状态)或者是二进制枚举来解决。

3. 代码如下:

dfs:

import collectionsclass Solution:res = None# 模拟每一个字母的两种选择: 对于2的余数是0还是1, mp是一个存储中间结果的哈希表这样在递归出口可以判断等式是否满足条件, x记录方案数目def dfs(self, u: int, x: int, s: str, mp: dict, mp1: collections.defaultdict, mp2: collections.defaultdict):# 递归出口if u == 7:# 判断当前每一种字母对应的奇数还是偶数的选择下最终等式对2的取余的结果是否是0if (mp["B"] + mp["I"]) * (mp["G"] + mp["O"] + mp["E"] + mp["S"]) * mp["M"] % 2 == 0:# 满足等式的要求self.res += xreturnc = s[u]# 尝试当前的字符对于2取余的结果为奇数的情况mp[c] = 1self.dfs(u + 1, x * mp1[c], s, mp, mp1, mp2)# 尝试当前的字符对于2取余的结果为偶数的情况mp[c] = 2self.dfs(u + 1, x * mp2[c], s, mp, mp1, mp2)def process(self):n = int(input())# mp1, mp2分别记录出现奇数次和偶数次的字母出现的次数是多少mp1, mp2 = collections.defaultdict(int), collections.defaultdict(int)for i in range(n):s = input().split()if int(s[1]) % 2 == 0:# 偶数mp2[s[0]] += 1else:# 奇数mp1[s[0]] += 1# 题目中出现的7个字母s = "BESIGOM"# 初始化全局变量self.res = 0self.dfs(0, 1, s, dict(), mp1, mp2)return self.resif __name__ == "__main__":print(Solution().process())

二进制:

import collectionsclass Solution:def process(self):n = int(input())# mp1, mp2分别用来统计出现奇数次数和偶数次数的字母出现的次数mp1, mp2 = collections.defaultdict(int), collections.defaultdict(int)for i in range(n):s = input().split()if int(s[1]) % 2:mp1[s[0]] += 1else:mp2[s[0]] += 1mp = dict()# 对应题目中的7个字母s = "BESIGOM"res = 0for i in range(1 << 7):for j in range(7):# 求解当前状态i对应的第j位是否是1mp[s[j]] = i >> j & 1# 判断等式是否满足要求if (mp["B"] + mp["I"]) * (mp["G"] + mp["O"] + mp["E"] + mp["S"]) * mp["M"] % 2 == 0:# 求解方案数目_sum = 1for j in range(7):if i >> j & 1:_sum *= mp1[s[j]]else:_sum *= mp2[s[j]]res += _sumreturn resif __name__ == "__main__":print(Solution().process())

1875 贝茜的报复(dfs、二进制)相关推荐

  1. 1875.贝茜的报复

    Powered by:NEFU AB-IN Link 文章目录 1875.贝茜的报复 题意 思路 代码 1875.贝茜的报复 题意 农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题. 约翰给贝茜出了一道相 ...

  2. 1875. 贝茜的报复

    题目描述 农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题. 约翰给贝茜出了一道相当难的问题,导致她没能解决. 现在,她希望通过给约翰出一道有挑战性的难题来报复他. 贝茜给了约翰一个表达式 (B+E+S+ ...

  3. AcWing 1875.贝茜的报复

    目录 题目 解题思路 C++代码 Java代码(带注释) 题目 农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题. 约翰给贝茜出了一道相当难的问题,导致她没能解决. 现在,她希望通过给约翰出一道有挑战性的 ...

  4. 贝茜的报复(dfs + 位运算)

    原题链接 本题关键在于二进制的转化,如果直接枚举每个字母(共7个字母)的20种可能就会TLE 另外需要了解以下公式: #include <iostream> #include <cs ...

  5. 寒假每日一题——贝茜的报复

    贝茜的报复 问题描述 农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题. 约翰给贝茜出了一道相当难的问题,导致她没能解决. 现在,她希望通过给约翰出一道有挑战性的难题来报复他. 贝茜给了约翰一个表达式 ( ...

  6. [BZOJ1643][Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪

    1643: [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: ...

  7. BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划

    题目 1613: [Usaco2007 Jan]Running贝茜的晨练计划 Time Limit: 5 Sec  Memory Limit: 64 MB Description 奶牛们打算通过锻炼来 ...

  8. bzoj 3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题(DP)

    3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: ...

  9. bzoj 1643: [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪(DP)

    1643: [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪 Time Limit: 5 Sec  Memory Limit: 64 MB Submit:  ...

最新文章

  1. Android Audio代码分析7 - stream type
  2. html验证座机号码_html5表单pattern属性配合正则验证电话和手机号码
  3. java 文件上传 jar_JavaWeb 之 使用 commons-fileupload.jar 实现文件上传
  4. Docker-Compose 使用简介
  5. 分析android动画模块[转]
  6. selenium使用浏览器隐私模式加载网站
  7. python物体跟着鼠标走_用Python写一个跟随鼠标运动的自定义窗口
  8. HTML的快速写法:Emmet和Haml
  9. Thinkphp结合phpqrcode生成二维码海报代码
  10. 【ANSYS】网格划分技术之映射网格
  11. 使用ActionForm的validate()进行验证
  12. 互联网公司常用的黑话,你中招了多少?
  13. (收藏)不错的敏捷迭代回顾会步骤
  14. 使用CVXQUAD时出现,函数或变量 ‘op_rel_entr_epi_cone‘ 无法识别。
  15. 工厂模式C++实现(三种工厂模式附详细注释)
  16. 基于JavaWeb的文献管理系统设计与实现
  17. Docker提交天池比赛代码流程(windows10环境下)
  18. 微软Xbox击败PS4 主导“黑五”游戏机市场
  19. SSM+在线纳新系统 毕业设计-附源码241540
  20. win7关机快捷键_总说win7最好用,不知这些强大的功能,怎知你的win10好不好用?...

热门文章

  1. unity 多台 显示器 控制_AB罗克韦尔自动化Micro820可编程逻辑控制器系统型号及功能介绍...
  2. 写简洁java代码的小技巧
  3. 群晖 使用SMB3进行局域网传输双倍叠加网速下踩的一些坑
  4. 深度学习原理-----线性回归+梯度下降法
  5. 完美扒站, 整站下载
  6. 用Python写个空课表生成器-Excel文件操作实例
  7. Android电池矫正方法
  8. Android MTK 放电曲线以及库轮值矫正
  9. (转)操作系统实现多线程的几种模式
  10. int *a和(int *)a的区别