C++解题思路,二维数组,求连续0的个数和次数

这篇博客记录了作者在找工作中遇到的一道C++编程题,题目要求在给定的二维数组中,计算可以在0的位置上额外放置多少人,使得每个人周围没有其他人。作者提供了两种不完善的解题思路,并分享了代码实现,讨论了连续0个数对应可放置人数的关系。在解题过程中,作者意识到基础不牢固,计划加强练习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在找工作,记录一下自己的解题思路,以便之后翻阅以及优化。

题目:输入行列数,1表示有人,0表示没人,要使得所有有人的位置上下左右都没有人,求给出的数组还能再多放置几个人?

思路一:(不完善)求数组中,为0的位置上下左右的人数之和(即看没人的位置,上下左右是否有人),可以得到另一个同行列的数组。在这个数组的基础上,求每行的0个数(0代表上下左右都没有人),单个0表示此位置可以放人,两个连续的0表示可以放一个人,三个连续的0表示可以放两个人,四个连续的0也只能放两个人。即放置的人个数x为(i+1)/2,i为连续0个数。代码如下:

#include<iostream>
#include<vector>
using namespace std;
int sumzero1(vector<int>&v){//求连续一个0个数
	int ans = 0;
	for (int i = 0; i < v.size(); i++){
		if (v[i] == 0){
			if (i == 0){
				if (v[i + 1] != 0)ans++;
			}
			else if (i == v.size() - 1){
				if (v[i - 1] != 0)ans++;
			}
			else{
				if (v[i - 1] != 0 && v[i + 1] != 0)ans++;
			}
		}
	}
	return ans;
}
int sumzero2(vector<int>&v){//求连续二个0个数
	int ans = 0;
	for (int i = 0; i < v.size()-1; i++){
		if (v[i] == 0){
			if (i == 0){
				if (v[i + 1] == 0&&v[i + 2] != 0)ans++;
			}
			else if (i == v.size() - 2){
				if (v[i - 1] != 0 && v[i + 1] == 0)ans++;
			}
			else{
				if (v[i - 1] != 0 && v[i + 1] == 0 && v[i +2] != 0)ans++;
			}
		}
	}
	return ans;
}
int sumzero3(vector<int>&v){//求连续三个0个数
	int ans = 0;
	for (int i = 0; i < v.size()-2; i++){
		if (v[i] == 0){
			if (i == 0){
				if (v[i + 1] == 0 && v[i + 2] == 0 && v[i + 3] != 0)a
<< 以下是一个完整的C++程序,实现了您的要。首先定义了一个`fun`函数用于删除重复元素,并且保留唯一的值。这个过程会直接修改输入的一维数组。此外为了清晰地展示结果,在主函数中进行了测试。 ```cpp #include <iostream> using namespace std; // 删除相同元素的函数 int fun(int a[], int n) { if (n == 0) return 0; // 如果数组为空,则直接返回 int index = 1; for (int i = 1; i < n; ++i) { if (a[i] != a[i - 1]) { // 检查当前元素是否与前一个不同 a[index++] = a[i]; // 不同则保存下来 } } return index; // 返回新长度 } int main() { int arr[] = {2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 10, 10, 10}; int size = sizeof(arr) / sizeof(arr[0]); cout << "原数组:" << endl; for (int i = 0; i < size; ++i) cout << arr[i] << ' '; cout << endl; // 调用fun函数移除重复项并获取新的大小 int newSize = fun(arr, size); cout << "处理后的数组:" << endl; for (int i = 0; i < newSize; ++i) cout << arr[i] << ' '; cout << endl; return 0; } ``` ### 解释: #### 思路分析: 由于给定的是已经排序好的数组(升序),所以只需从前至后遍历整个数组即可完成任务。对于每个元素与其前面相邻的一个进行比较。如果两者相等就跳过;否则将该不等于上一项的新值存入指定位置处形成一个新的子序列。 - 初始化两个变量 `index=1`,用来记录最终有效数字的位置; - 遍历从第二个开始直到最后一个元素为止(`for loop`)检查每一个数值是否不同于它的前置位数(`if statement`) ; - 当发现不一样的时候就把此独特值得到赋值回原来的地方,并让索引增加一步继续往下做同样操作直至结束循环得到答案. 因此我们只需要O(n)时间复杂度就能解决问题而不是使用额外空间存储临时结果再复制回去这样的做法更高效简单明了. #### 注意事项: 本解决方案假设输入数组至少包含一个元素。如果有空数组的情况发生时需特殊考虑避免非法内存访问等问题出现错误提示或崩溃状况发生几率增大很多倍以上情况都需要程序员自己手动添加相应逻辑判断语句确保边界条件正常运作无误才能保证整体正确执行下去达到预期目标效果最佳化程度最高水平状态才行哦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值