农夫约翰和奶牛贝茜喜欢在业余时间互相出数学题。
约翰给贝茜出了一道相当难的问题,导致她没能解决。
现在,她希望通过给约翰出一道有挑战性的难题来报复他。
贝茜给了约翰一个表达式 ,其中包含七个变量
(
是变量,不是零)。
对于每个变量,她给约翰一个列表,表中包含该变量可采用的最多 个整数值。
她要求约翰计算,共有多少种给变量赋值的方法可以使得表达式的计算结果为偶数。
输入格式
第一行包含一个整数 。
接下来 行,每行包含一个变量和该变量的一个可能值。
每个变量至少出现 次,最多出现
次。
同一变量不会重复列出同一可能值。
输出格式
输出可以使得表达式的计算结果是偶数的给变量赋值的方法总数。
数据范围,
所有变量的可能取值范围
本题答案不会超出 范围。
输入样例:
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)
,虽然计算结果相同,但是赋值方式不同,所以要分别计数。
解法一
// M 2, 19
// B 2, 3
// I 9, 10
// G 1
// O 16
// E 5
// S 7
using namespace std;
vector<int> q[10];
unordered_map<char, int> mp;
int cnt[10], even[10], odd[10];
// O(20^4=160000)
int dfs(int x, int sum){
if(x == 7){
if(sum % 2) return 0;
return 1;
}
int res = 0;
for(auto n: q[x]){
res += dfs(x + 1, sum + n);
}
return res;
}
int solve(){
int res = 0;
// M 为偶数
res += even[0] * (cnt[1] * cnt[2] * cnt[3] * cnt[4] * cnt[5] * cnt[6]);
// B + I 为偶数
res += odd[1] * odd[2] * (cnt[3] * cnt[4] * cnt[5] * cnt[6]) * odd[0];
res += even[1] * even[2] * (cnt[3] * cnt[4] * cnt[5] * cnt[6]) * odd[0];
// G + O + E + S 为偶数
int ans = dfs(3, 0);
res += ans * (odd[0] * (odd[1] * even[2] + odd[2] * even[1]));
return res;
}
int main(){
int n;
cin >> n;
mp['M'] = 0;
mp['B'] = 1;
mp['I'] = 2;
mp['G'] = 3;
mp['O'] = 4;
mp['E'] = 5;
mp['S'] = 6;
char a;
int b;
while(n--){
cin >> a >> b;
q[mp[a]].push_back(b);
cnt[mp[a]]++;
if(b % 2) odd[mp[a]]++; // 奇数
else even[mp[a]]++; // 偶数
}
cout << solve() << endl;
return 0;
}
解法二
// M 2, 19
// B 2, 3
// I 9, 10
// G 1
// O 16
// E 5
// S 7
// 可以发现答案的奇偶只与每个变量取奇偶有关,则一种变量有两种取值(可用二进制表示,0表示偶数,1表示奇数)
// 所以共有2^7=128种选法
using namespace std;
// O(2^7=128)
int main(){
int n;
cin >> n;
unordered_map<char, int> cnt[2];
char a;
int b;
while(n--){
cin >> a >> b;
cnt[abs(b) % 2][a]++;
}
char str[] = "BESIGOM";
int res = 0;
unordered_map<char, int> v;
for(int i = 0; i < 1 << 7;i++){
for(int j = 0; j < 7; j++) v[str[j]] = i >> j & 1;
if((v['B'] + v['I']) * (v['G'] + v['O'] + v['E'] + v['S']) * v['M'] % 2 == 0){
int sum = 1;
for(int j = 0; j < 7; j++) sum *= cnt[i >> j & 1][str[j]];
res += sum;
}
}
cout << res << endl;
return 0;
}