This solution runs in O(MN) time with a constant factor (5) in 79ms. The idea is to create a 2D matrix to store kills and loop through all rows and while looping through each row find a kill streak until a wall appears. Then assign that kill streak to previous cells and reset it to 0. Do the same for all columns and add to the 2D matrix. Then at the end loop over all cells to find the maximum number of kills. I haven't abstracted the code to make it shorter but it should be easy to understand!

```
int maxKilledEnemies(vector<vector<char>>& grid) {
if (grid.size() == 0) return 0;
int M = grid.size(), N = grid[0].size();
// 2D matrix MxN to store maximum number of killed enemies starting at each square:
vector<vector<int>> KILLS (M,vector<int>(N,0));
// Loop through all the rows in the matrix and update KILLS:
for (int i = 0; i < M; ++i) {
int rowCount = 0, rowCountStartIndex = 0;
for (int j = 0; j < N; ++j) {
if (grid[i][j] == 'W') {
// Update kills for this streak in rows until this wall was hit:
for (int k = rowCountStartIndex; k < j; ++k) KILLS[i][k] = rowCount;
rowCount = 0;
rowCountStartIndex = j+1;
} else if (grid[i][j] == 'E') {
rowCount++;
}
}
// Update past rows if we didn't hit a wall at the end index:
for (int k = rowCountStartIndex; k < N; ++k) KILLS[i][k] = rowCount;
}
// Loop through all the columns in the matrix and update KILLS:
for (int j = 0; j < N; ++j) {
int colCount = 0, colCountStartIndex = 0;
for (int i = 0; i < M; ++i) {
if (grid[i][j] == 'W') {
// Update kills for this streak in cols until this wall was hit:
for (int k = colCountStartIndex; k < i; ++k) KILLS[k][j] += colCount;
colCount = 0;
colCountStartIndex = i+1;
} else if (grid[i][j] == 'E') {
colCount++;
}
}
// Update past cols if we didn't hit a wall at the end index:
for (int k = colCountStartIndex; k < M; ++k) KILLS[k][j] += colCount;
}
int maxKills = 0;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (grid[i][j] == '0' && KILLS[i][j] > maxKills) maxKills = KILLS[i][j];
}
}
return maxKills;
}
```