C++题解打卡Day 1——错误信息

【题目描述】

  宠物狗旺财躲在数轴上的某处。小H收到到了 𝑁 条信息,每条信息是下面种之一:

   ● <= 𝑥:表示旺财躲在小于或等于 𝑥 的某个位置。
   ● >= 𝑥:表示旺财躲在大于或等于 𝑥 的某个位置。

  不幸的是,这些信息不一定都正确,现在需要你帮助小H统计错误信息的最小数量。

【输入格式】

  输入的第一行包含 𝑁。
  以下 𝑁 行每行包含一条信息,格式见题目描述。

【输出格式】

  输出错误信息的最小数量。

【输入输出样例】

        Input   

6
>= 3
<= 7
<= 5
>= 6
>= 8
<= 4

        Output

2

【题解】

       设 x[1]..x[n] 读入n条信息的x,也是旺财藏身的所有可能的位置
     设 a[1]..a[na] 表示说 >=x 的数据,
     设 b[1]..b[na] 表示说 <=x 的数据,

     100分解法:排序+枚举+查找算法:

     1)、将3个数组均由小到大排序;

     2)、枚举旺财可能藏身的位置:x[1],x[2],……x[n]

      ● 假设狗藏在 x[k] 这个位置,则按下面方法计算此时错误信息数:
      ● 在a[1]..a[na]中查找有多少个元素大于x[k],假设有s1个(不正确数);
      ● 在b[1]..b[nb]中查找有多少个元素小于x[k],假设有s2个(不正确数);
      ●所以Ans=min(Ans,s1+s2)

   至于查找:可以用二分查找,也可以利用单调性,用不回头顺序查找优化!

   时间复杂度:
    不回头顺序查找:O(n+n)
    二分查找:O(nlogn)

【Code】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int n,x[MAXN],a[MAXN],b[MAXN],na,nb,ans = 10000000;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 1;i <= n;i++){
		string s;
		int y;
		cin >> s >> y;
		x[i] = y;
		if(s == ">="){
			na++;
			a[na] = y;
		}
		if(s == "<="){
			nb++;
			b[nb] = y;
		}
	}
	sort(x + 1,x + 1 + n);
	sort(a + 1,a + 1 + na);
	sort(b + 1,b + 1 + nb);
	for(int i = 1;i <= n;i++){
		int p = upper_bound(a + 1,a + 1 + na,x[i]) - a;
		int s1 = na - p + 1;
		p = lower_bound(b + 1,b + 1 + nb,x[i]) - b;
		int s2 = p - 1;
		ans = min(ans,s1 + s2);
	}
	cout << ans;
	return 0;
}

【补充知识——C++二分查找函数】

        【upper_bound】

   upper_bound 是 C++ 标准库中的一个函数模板,它定义在 <algorithm> 头文件中。这个函数用于在一个已排序的范围内查找第一个大于给定值的元素。如果所有元素都不大于给定值,则返回范围的结束迭代器。

        具体来说,upper_bound 接收四个参数:前两个参数指定了要搜索的范围(开始迭代器和结束迭代器),第三个参数是要查找的值,而第四个参数(可选)是比较函数,用于确定元素是否应该被认为在查找的值之前(默认为小于)。

        函数返回的是一个迭代器,指向第一个大于给定值的元素,如果所有元素都不大于给定值,则返回范围的结束迭代器。

        以下是该函数的函数签名(C++20前)

template< class ForwardIt, class T >  
ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value );

        例子:

#include <algorithm>  
#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> v = {1, 2, 4, 4, 5, 6};  
  
    // 查找第一个大于4的元素  
    auto it = std::upper_bound(v.begin(), v.end(), 4);  
  
    if (it != v.end()) {  
        std::cout << "The first element greater than 4 is " << *it << std::endl;  
    } else {  
        std::cout << "No element is greater than 4" << std::endl;  
    }  
  
    return 0;  
}

        在这个例子中,upper_bound 将返回指向元素 5 的迭代器,因为它是范围内第一个大于 4 的元素。

        【lower_bound】

   lower_bound 是 C++ 标准库中的一个函数模板,它定义在 <algorithm> 头文件中。这个函数用于在一个已排序的范围内查找第一个不小于(即大于等于)给定值的元素。如果所有元素都小于给定值,则返回范围的结束迭代器。

        函数签名通常如下所示:

template< class ForwardIt, class T >  
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value );  

        例子:

#include <algorithm>  
#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> v = {1, 2, 4, 4, 5, 6};  
  
    // 查找第一个不小于4的元素  
    auto it = std::lower_bound(v.begin(), v.end(), 4);  
  
    if (it != v.end()) {  
        std::cout << "The first element not less than 4 is " << *it << std::endl;  
    } else {  
        std::cout << "No element is not less than 4" << std::endl; // 这行实际上永远不会执行,因为v中至少有一个元素不小于4  
    }  
  
    // 输出将是 "The first element not less than 4 is 4"  
  
    return 0;  
}

完结撒花!

特别鸣谢:文心一言

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:这段代码是一个解决LeetCode上某个题目的C++实现,具体是一个双指针的解法。该题目是计算一个数组中的积水量。代码中使用了两个指针分别指向数组的左右边界,然后通过比较左右指针所指向的元素的大小,来确定当前位置的积水量。具体的计算方法是,如果左指针所指向的元素小于右指针所指向的元素,则对左指针的左边进行操作,如果左指针所指向的元素大于等于右指针所指向的元素,则对右指针的右边进行操作。在每一次操作中,都会更新左边的最大值和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[1\] 引用\[2\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个深度优先搜索的解法。该题目是计算一个二维网格中从起点到终点的可行路径数量。代码中使用了递归的方式进行深度优先搜索,从起点开始,每次向下或向右移动一步,直到到达终点。在每一步移动中,会判断当前位置是否有障碍物,如果有障碍物则返回0,如果到达终点则返回1,否则继续递归搜索下一步的位置。最后返回总的可行路径数量。\[2\] 引用\[3\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个动态规划的解法。该题目是计算一个数组中的积水量。代码中使用了动态规划的思想,通过遍历数组中的每个元素,分别计算该元素左边和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[3\] 综上所述,这三段代码分别是解决LeetCode上不同题目的C++实现,分别使用了双指针、深度优先搜索和动态规划的方法来解决问题。 #### 引用[.reference_title] - *1* *3* [Leetcode 热题100 42.接雨水(C++ 多种解法,错过可惜)](https://blog.csdn.net/qq_51933234/article/details/124637883)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[C++]Leetcode 不同路径 || 解题思路及详解](https://blog.csdn.net/weixin_62712365/article/details/123951736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值