大概题意:给出一个H*W的矩阵,叫你求出把矩阵中的H行W列中o的数量>=k的修改o的次数,我们可以把.改成o,求操作次数最少的
例:
#2
#3
OK,那我们先构建一个S[ ][ ]来储存我们的输入,但是题目并没有给出H,W的大小,只给出了:H×W≤2×10^5,不排除极限情况(H=2*10^5,W=1)我们定一个S[2*1e5][2*1e5]的数组,除非你的运行空间超大,不然肯定爆,此时肯定就有小伙伴要说:先开个string s[2*1e5]不就OK了
于是1.0暴力版本新鲜出炉:
#include
using namespace std;
int h, w, k;
string s[20020], b1[200020], b2[200020];
int ans1 = 0x3f3f3f3f, ans2 = 0x3f3f3f3f;
void qz() {
for (int i = 0; i < w; i++)//b1->得到s[]的列
for (int j = 0; j < h; j++)
b1[i][j] = s[j][i];
for (int i = 0; i < h; i++)//b2->得到s[]的行
for (int j = 0; j < w; j++)
b2[i][j] = s[i][j];
}
int main() {
cin >> h >> w >> k;
for (int i = 0; i < h; i++)//输入
cin >> s[i];
qz();//获得s[]的行与列
for (int i = 0; i < w; i++) {
int sx = 0, so = 0;
for (int j = 0; j < h; j++) {
if (b1[i][j] == 'x') sx++;//如果b1[i][j]==x,x的出现次数增加
if (b1[i][j] == 'o') so++;//如果b1[i][j]==o,o的出现次数增加
}
if (so >= k) cout << 0, exit(0); //如果o出现次数本来就>=k输出0,结束程序(exit(0))
else if (sx + so == w) continue; //如果o出现次数+x出现次数==w,无法修改,continue
else if (w - sx < k) continue; //w-如果x出现次数= k) cout << 0, exit(0);
else if (so + sx == h) continue;
else if (w - sx < k) continue;
else ans2 = min(ans2, k - so);
}
min(ans1, ans2) != 0x3f3f3f3f ? cout << min(ans1, ans2) : cout << -1;
/*
相当于:if(min(ans1,ans2)!=0x3f3f3f3f)
cout<
然后你就会发现错了4个点
好,接下来展开优化:滑动窗口(不懂得看这:滑动窗口详解_窗口滑动-CSDN博客)
于是,我们可以开始魔法:
#include
#define inf 0x3f3f3f3f
#define endl "\n"
using namespace std;
int n, m, k;
int sx, so;
const int N = 1e7;
string s[N];
int ans = inf;
int main() {
cin >> n >> m >> k;
for (int i = 0; i < n; i++) {
cin >> s[i];
}
for (int i = 0; i < n; i++) {
sx = so = 0;
for (int j = 0; j < k; j++) {
if (s[i][j] == 'x') sx++;
if (s[i][j] == 'o') so++;
}
if (sx == 0) ans = min(ans, k - so);
for (int j = k; j < m; j++) {
if (s[i][j - k] == 'x') sx--;
if (s[i][j - k] == 'o') so--;
if (s[i][j] == 'x') sx++;
if (s[i][j] == 'o') so++;
if (sx == 0) ans = min(ans, k - so);
}
}
for (int i = 0; i < m; i++) {
sx = so = 0;
for (int j = 0; j < k; j++) {
if (s[j][i] == 'x') sx++;
if (s[j][i] == 'o') so++;
}
if (sx == 0) ans = min(ans, k - so);
for (int j = k; j < n; j++) {
if (s[j - k][i] == 'x') sx--;
if (s[j - k][i] == 'o') so--;
if (s[j][i] == 'x') sx++;
if (s[j][i] == 'o') so++;
if (sx == 0) ans = min(ans, k - so);
}
}
ans != inf ? cout << ans : cout << -1;
return 0;
}
然后当你激动的测完样例提交时:
裂了( ఠൠఠ )ノ
哦,原来要加一个if()!!!!
AC代码
#include
#define inf 0x3f3f3f3f
#define endl "\n"
using namespace std;
int n, m, k;
int sx, so;
const int N = 1e7;
string s[N];
int ans = inf;
int main() {
cin >> n >> m >> k;
for (int i = 0; i < n; i++) {
cin >> s[i];
}
if (m >= k)//对,要判断,不然卡死循!!!
for (int i = 0; i < n; i++) {
sx = so = 0;
for (int j = 0; j < k; j++) {
if (s[i][j] == 'x') sx++;
if (s[i][j] == 'o') so++;
}
if (sx == 0) ans = min(ans, k - so);
for (int j = k; j < m; j++) {
if (s[i][j - k] == 'x') sx--;
if (s[i][j - k] == 'o') so--;
if (s[i][j] == 'x') sx++;
if (s[i][j] == 'o') so++;
if (sx == 0) ans = min(ans, k - so);
}
}
if (n >= k)
for (int i = 0; i < m; i++) {
sx = so = 0;
for (int j = 0; j < k; j++) {
if (s[j][i] == 'x') sx++;
if (s[j][i] == 'o') so++;
}
if (sx == 0) ans = min(ans, k - so);
for (int j = k; j < n; j++) {
if (s[j - k][i] == 'x') sx--;
if (s[j - k][i] == 'o') so--;
if (s[j][i] == 'x') sx++;
if (s[j][i] == 'o') so++;
if (sx == 0) ans = min(ans, k - so);
}
}
ans != inf ? cout << ans : cout << -1;
return 0;
}