时间限制: 1 Sec 内存限制: 128 MB
题目描述
学佛Fife最喜欢Bemy上的数学课了。因为他可以在数学课上尽情的蒸发学水~
Bemy为了不让学佛Fife过度骄傲,以保证每一个学水都能不被他影响,自信地不断地进步,给Fife一个有挑战性的数学题。
因为Fife不想让妹子Maze等得太久,决定把这道题交给你。
题目是这样的:有一个表达式(B+E+S+S+I+E)(G+O+E+S)(M+O+O)
其中B,E,S,I,G,O,M为七个变量(注意“O”是变量不是0)。
对于每个变量,Bemy会告诉Fife这个变量所代表的各个可能值。
Bemy想问问Fife这样一个问题:原表达式有多少种可能的情况,使表达式的值为偶数。(只要有一个变量的值不同,即为一种情况)
输入
第一行输入包含一个整数N。
下一个N 行每行包含一个变量名称和一个这个变量可以使用的值。
注:每个变量在整张表中不会出现多于20 次。
同一个变量不存在两个相同的值。所有给出的值都在-300……300 之间。
输出
打印出一个整数,表示有多少种方法使表达式的值为一个偶数。
样例输入
10
B 2
E 5
S 7
I 10
O 16
M 19
B 3
G 1
I 9
M 2
样例输出
6
思路:
题目要求表达式值为偶数,其实我们只要保证有一个括号内的和是偶数,就能确定整个表达式的值是偶数。
先看第一个括号内的数,B+I+S+S+E+E,因为偶数 + 偶数 = 偶数,又因为S+S+E+E 是偶数,所以我们只要确定 B + I 是不是偶数,就可以判断这个括号内的数字之和是不是偶数,也就是说这个括号和的奇偶是由 B + I 决定的,同理,第二个括号由 G + O + E + S 决定,第三个括号由 M 决定。
接下来我们把第一个括号的和为偶数的情况设为 A 类;
第二个括号的和为偶数的情况设为 B 类;
第三个括号的和为偶数的情况设为 C 类;
根据容斥原理得:
(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)
( 文字翻译为A类和B类和C类元素个数总和= A类元素个数+ B类元素个数+C类元素个数—既是A类又是B类的元素个数—既是A类又是C类的元素个数—既是B类又是C类的元素个数+既是A类又是B类而且是C类的元素个数。)
此式结果就是我们想要的答案
下面是代码:
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=2e5+10;
char s[7]={'B','I','S','E','G','O','M'};
vector<int>v[200];
int n,m,fa,fb,fc,oa,ob,oc;//后 6个变量分别代表第一、二、三个括号内所有的方案数
char ch; //与第一、二、三括号内数字和为偶数的方案数
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ch>>m;
v[ch].push_back(m);
}
fa=v[s[0]].size()*v[s[1]].size();
fb=v[s[2]].size()*v[s[3]].size()*v[s[4]].size()*v[s[5]].size();
fc=v[s[6]].size();
for(int i=0;i<v[s[0]].size();i++)
{
for(int j=0;j<v[s[1]].size();j++)
{
if((v[s[0]][i]+v[s[1]][j])%2==0) oa++;
}
}
for(int i=0;i<v[s[2]].size();i++)
{
for(int j=0;j<v[s[3]].size();j++)
{
for(int k=0;k<v[s[4]].size();k++)
{
for(int z=0;z<v[s[5]].size();z++)
{
if((v[s[2]][i]+v[s[3]][j]+v[s[4]][k]+v[s[5]][z])%2==0) ob++;
}
}
}
}
for(int i=0;i<v[s[6]].size();i++)
{
if(v[s[6]][i]%2==0) oc++;
}
ll ans=oa*fb*fc+ob*fa*fc+oc*fa*fb-oa*ob*fc-oa*oc*fb-ob*oc*fa+oa*ob*oc;
//(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)
cout<<ans;
return 0;
}