贝茜的报复

题解AcWing 1875 贝茜的报复

题目描述:
农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题。

约翰给贝茜出了一道相当难的问题,导致她没能解决。

现在,她希望通过给约翰出一道有挑战性的难题来报复他。

贝茜给了约翰一个表达式 (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
题目分析:

因为题目已经给出了表达式,已知一个变量最多有20种取值,那么暴力来求解的话就有20^7 = 1280000000种情况,肯定超出了1s的时间限制,所以要考虑优化。
而这个题目只要求求出使结果是偶数的情况,偶数是做取模运算,取模运算常用性质:(a+b) mod c= (a mod c) + (b mod c),所以可以对每个变量先取模,就变成了2^7=128种情况,此时可以枚举。同时在枚举每一种情况时,由于有两个S和E,和一定为偶数,所以可以忽略。所以就只剩下遍历(B+I), (G+O+E+S), (M)共7种情况。如果三个因子里面有一个是偶数,那么答案就一定是偶数(奇数 * 奇数=奇数,偶数 * 偶数 = 偶数 , 奇 * 偶 = 偶)

#include<algorithm>
#include<iostream>
using namespace std;

int ans;
map<char, int> mp1, mp2, a;	//mp1存每一个字母奇数的个数,a表示
string s = "BESIGOM";
void dfs(int u, int x)
{
    if(u == 7)
    {
        if((a['B'] + a['I']) % 2 
           && (a['G'] + a['O'] + a['E'] + a['S']) % 2 
           && a['M'] % 2 ) return; //如果都是1表示都是奇数,此时肯定是奇数
        //如果满足有一个是偶数,则算上这种情况
        ans += x;
        return;
    }
    char ch = s[u];
    a[ch] = 1;
    dfs(u+1, x * mp1[ch]);	//遍历ch是奇数的情况
    a[ch] = 2;
    dfs(u+1, x * mp2[ch]);	//遍历ch是偶数的情况
}

int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        char c;
        int x;
        cin >> c >> x;
        if(x%2 == 1) mp1[c]++;	//c字母为奇数的情况加一
        else mp2[c]++;
    }
    dfs(0, 1);	//从第一层开始遍历
    cout << ans;
    return 0;
}
//代码是嫖大佬的题解来的:https://www.acwing.com/solution/content/86729/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值