Cerinta completa
A war has broken down between Vim and Emacs. Gedit, being Vim’s ally, is captured by Emacs as a prisoner of war and it is up to Vim to rescue him by defeating Emacs.
For this task, Vim has to assemble an army of appropriate skills. He can choose a non-empty subset of soldiers from a set of soldiers (numbered from to ). Each soldier has some subset of skills out of different skills (numbered from to ). The skill-set of an army is the union of skill-sets of its constituent soldiers. To win the war, Vim needs to know how many different subsets of soldiers satisfy his skill-set requirement. Since the answer can be huge, print it modulo .
Note : The chosen army’s skill-set must exactly match the skill-set requirement of Vim (i.e no extra skills must be present in the army’s skill-set than what is required).
Input Format
The first line contains and , the number of soldiers to choose from and the number of different skills possible respectively.
The next lines contain boolean characters each. If the character of the line is , then the soldier possess the skill and if it is , then not.
The last line contains boolean characters denoting the requirement skill-set of Vim where the character being signifies that Vim wants the skill to be present in his final army and not, otherwise.
Constraints
Output Format
Output in a single line the required answer, as explained above.
Sample Input
4 2
00
10
01
11
11
Sample Output
10
Explanation
Vim wants both the skills to be present in his selected army. Hence, he can choose the following subsets of soldiers:
Limbajul de programare folosit: cpp14
Cod:
// vim-war.cpp
// Vim War
// Week of Code 16
// Author: derekhh
// Jul 9, 2015
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 100000;
const int MAXM = 20;
const int MOD = 1000000007;
int originalSkill[MAXN];
int f[1 << MAXM][MAXM + 1];
int modexp(int a, int b) {
long long res = 1 % MOD, val = a % MOD;
while (b) {
if (b & 1)
res = (res * val) % MOD;
val = (val * val) % MOD;
b >>= 1;
}
return (int)res;
}
int main() {
int n, m;
char str[MAXM + 1];
scanf("%d %d\n", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", str);
int val = 0;
for (int j = 0; j < m; j++)
val = val * 2 + (str[j] - '0');
originalSkill[i] = val;
}
int target = 0, newm = 0;
scanf("%s", str);
for (int i = 0; i < m; i++) {
if (str[i] == '1') {
target = target * 2 + 1;
newm++;
}
}
for (int i = 0; i < n; i++) {
int val = 0;
bool flag = true;
for (int j = m - 1; j >= 0; j--) {
if (str[m - j - 1] == '1') {
if (originalSkill[i] & (1 << j)) val = val * 2 + 1;
else val *= 2;
}
else {
if (originalSkill[i] & (1 << j)) {
flag = false;
break;
}
}
}
if (flag) f[val][newm]++;
}
for (int j = newm; j > 0; j--) {
for (int i = 0; i < (1 << newm); i++) {
f[i][j - 1] += f[i][j];
int val = (i & (1 << (j - 1)));
if (val == 0) {
f[i | (1 << (j - 1))][j - 1] += f[i][j];
}
}
}
/*
for (int i = 0; i < (1 << newm); i++) {
printf("f[%d][0] = %d\n", i, f[i][0]);
}
*/
int ans = 0;
for (int i = 0; i < (1 << newm); i++) {
int cnt = 0;
for (int j = 0; j < newm; j++) {
if (i & (1 << j))
cnt++;
}
int val = modexp(2, f[i][0]);
if (cnt % 2 == newm % 2) ans = (ans + val) % MOD;
else ans = (ans - val + MOD) % MOD;
}
if (target == 0)
printf("%d\n", (ans - 1 + MOD) % MOD);
else
printf("%d\n", ans);
return 0;
}
Scor obtinut: 1.0
Submission ID: 464605010
Link challenge: https://www.hackerrank.com/challenges/vim-war/problem
