Cheating Gomoku Narabe(atcoder.jp)

原题再现

(全英无翻译)D - Cheating Gomoku Narabe (atcoder.jp)icon-default.png?t=N7T8https://atcoder.jp/contests/abc337/tasks/abc337_d


       解释题意

        大概题意:给出一个H*W的矩阵,叫你求出把矩阵中的H行W列中o的数量>=k的修改o的次数,我们可以把.改成o求操作次数最少的

        例:

        #1

        #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 <bits/stdc++.h>
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,无法修改,continue
		else ans1 = min(ans1, k - so);		//取我们要修改的值的最小值
	}
	for (int i = 0; i < h; i++) {//同b1
		int sx = 0, so = 0;
		for (int j = 0; j < w; j++) {
			if (b2[i][j] == 'x') sx++;
			if (b2[i][j] == 'o') so++;
		}
		if (so >= 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<<min(ans1,ans2);
			else
				cout<<-1;
	*/
	return 0;
}

        然后你就会发现错了4个点

        好,接下来展开优化:滑动窗口(不懂得看这:滑动窗口详解_窗口滑动-CSDN博客

        于是,我们可以开始魔法:

        

#include <bits/stdc++.h>
#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 <bits/stdc++.h>
#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;
}

        OK啊,感谢观看

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-22 11:02:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-22 11:02:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-22 11:02:02       87 阅读
  4. Python语言-面向对象

    2024-01-22 11:02:02       96 阅读

热门阅读

  1. SQL Server修改数据字段名的方法

    2024-01-22 11:02:02       58 阅读
  2. SQL笔记 -- 多版本并发控制(MVCC)

    2024-01-22 11:02:02       52 阅读
  3. Armv8-M的TrustZone技术解决的安全需求

    2024-01-22 11:02:02       69 阅读
  4. P2P DMA发展全景分析解读

    2024-01-22 11:02:02       55 阅读
  5. 【python学习】面向对象编程3

    2024-01-22 11:02:02       58 阅读
  6. LeetCode 每日一题 Day 47 - 50

    2024-01-22 11:02:02       57 阅读
  7. C++面试:向量vector和列表list介绍

    2024-01-22 11:02:02       48 阅读