今天好不容易30分钟把前两题做出来了(第一题开始没看懂意思,搞了蛮久,第二题感觉不太像中等题的难度),第三题难得的很快有思路,但是细节有点多,然后写了半天,提交报错,排错,又报错,再排除然后一个小时就结束了,终于比赛结束后才发现。。。我只考虑了以某个点为转折点的两条路先:向右转向下和和向左转向上。。。没想到他有四条路线。。。我这也太笨了!最后贴上我最终ac的代码:
class Solution
{
public:
int maxTrailingZeros(vector<vector<int>> &grid)
{
int m = grid.size();
int n = grid[0].size();
int rst = 0;
int i, j, x, cnt, cnt2, cnt5, cnt2Right, cnt2Down, cnt5Right, cnt5Down;
vector<vector<vector<int>>> dp2(m + 1, vector<vector<int>>(n + 1, vector<int>(2, 0)));
vector<vector<vector<int>>> dp5(m + 1, vector<vector<int>>(n + 1, vector<int>(2, 0)));
// dp2[i][j][0]表示i - 1,j - 1处水平向左的乘积2的个数
// dp2[i][j][1]表示i - 1,j - 1处垂直s向上的乘积2的个数
// dp5[i][j][0]表示i - 1,j - 1处水平向左的乘积5的个数
// dp5[i][j][1]表示i - 1,j - 1处垂直向上的乘积5的个数
for(i = 1; i <= m; ++i)
{
for (j = 1; j <= n; ++j)
{
x = grid[i - 1][j - 1];
cnt2 = cnt5 = 0;
while(x % 2 == 0)
{
++cnt2;
x >>= 1;
}
while(x % 5 == 0)
{
++cnt5;
x /= 5;
}
dp2[i][j][0] = dp2[i][j - 1][0] + cnt2;
dp2[i][j][1] = dp2[i - 1][j][1] + cnt2;
dp5[i][j][0] = dp5[i][j - 1][0] + cnt5;
dp5[i][j][1] = dp5[i - 1][j][1] + cnt5;
}
}
for (i = 1; i <= m; ++i)
{
for (j = 1; j <= n; ++j)
{
//以i - 1,j - 1处为转折
cnt2Right = dp2[i][n][0] - dp2[i][j - 1][0];//i - 1,j - 1处水平向右的乘积2的个数
cnt2Down = dp2[m][j][1] - dp2[i - 1][j][1];//i - 1, j - 1处垂直向下的乘积2的个数
cnt5Right = dp5[i][n][0] - dp5[i][j - 1][0]; // i - 1,j - 1处水平向右的乘积5的个数
cnt5Down = dp5[m][j][1] - dp5[i - 1][j][1]; // i - 1, j - 1处垂直向下的乘积5的个数
cnt2 = dp2[i][j][0] - dp2[i][j - 1][0];
cnt5 = dp5[i][j][0] - dp5[i][j - 1][0];
cnt = max(
max(
min(dp2[i][j][0] + cnt2Down - cnt2, dp5[i][j][0] + cnt5Down - cnt5), //自该行最左端向右到i - 1, j - 1处转向下
min(dp2[i][j][0] + dp2[i][j][1] - cnt2, dp5[i][j][0] + dp5[i][j][1] - cnt5) //自该行最左端向右到i - 1, j - 1处转向上
),
max(
min(dp2[i][j][1] + cnt2Right - cnt2, dp5[i][j][1] + cnt5Right - cnt5), //自该行最右端向左到i - 1, j - 1处转向上
min(cnt2Down + cnt2Right - cnt2, cnt5Down + cnt5Right - cnt5) //向该行最右端向左到i - 1, j - 1处转向下
));
if(cnt > rst)
rst = cnt;
}
}
return rst;
}
};