前言
比赛时曾因为复制相似代码未改变量名浪费了,在比赛结束前因网络问题未提交成功。比赛以分遗憾告终。
提交后又因数组问题,尝试多次才。
思路
本题可以通过的时间复杂度进行预处理。
记录四个行列前缀和数组。
第列中,第到个字符中 .的个数。
第列中,第到个字符中 . 的个数。
第列中,第到个字符中 x 的个数。
第列中,第到个字符中 x的个数。
像前缀和一样推出每一项。
然后对于数组,记录以为第一项的行与列的最小修改次数。
(若为第一项的行与列中有 x,则值为)
有转移式:
当时(这一段没有x )
当时(这一段没有x )
易错点
因为此处数组大小不是常量,
注意数组大小,当数组大小<0时,就会运行错误
也可以用vector避免此类问题。
例如用这样的判断语句避免或的问题
if(w < n) size1 = 1;
if(h < n) size2 = 1;
int a[h][size1],b[size2][w],num1[h][w],num2[h][w],num3[h][w],num4[h][w];
code
for(int i = 0;i < h;i ++){
for(int j = 0;j < w;j ++){
int tmp1 = 0,tmp2 = 0;
if(s[i][j] == '.') tmp1 = 1;
else if(s[i][j] == 'x') tmp2 = 1;
if(j == 0){
num1[i][j] = tmp1;
num3[i][j] = tmp2;
}
else{
num1[i][j] = num1[i][j - 1] + tmp1;
num3[i][j] = num3[i][j - 1] + tmp2;
}
}
}
for(int i = 0;i < h;i ++){
for(int j = 0;j < w;j ++){
int tmp1 = 0,tmp2 = 0;
if(s[i][j] == '.') tmp1 = 1;
else if(s[i][j] == 'x') tmp2 = 1;
if(i == 0){
num2[i][j] = tmp1;
num4[i][j] = tmp2;
}
else{
num2[i][j] = num2[i - 1][j] + tmp1;
num4[i][j] = num4[i - 1][j] + tmp2;
}
}
}
for(int i = 0;i < h;i ++){
for(int j = 0;j <= w - n;j ++){
if(j == 0){
if(num3[i][j + n - 1] == 0){
a[i][j] = num1[i][j + n - 1];
ans = min(ans,a[i][j]);
}
}else{
if(num3[i][j + n - 1] - num3[i][j - 1] == 0){
a[i][j] = num1[i][j + n - 1] - num1[i][j - 1];
ans = min(ans,a[i][j]);
}
}
}
}
for(int j = 0;j < w;j ++){
for(int i = 0;i <= h - n;i ++){
if(i == 0){
if(num4[i + n - 1][j] == 0){
b[i][j] = num2[i + n - 1][j];
ans = min(ans,b[i][j]);
}
}else{
if(num4[i + n - 1][j] - num4[i - 1][j] == 0){
b[i][j] = num2[i + n - 1][j] - num2[i - 1][j];
ans = min(ans,b[i][j]);
}
}
}
}