1 条题解
-
1
题意分析
题目背景设定在一个特殊情境中,修士们面临着院长要求机器找出和为的两个数的任务,而机器仅能判断两数之和与的大小关系。现在有两个修士各自准备了一个整数列表,需要判断是否能从这两个列表中挑选出两个数,使它们的和恰好等于。
输入条件:输入包含两个列表,每个列表的第一行是该列表数字的数量,取值范围是 。接着是行,每行一个整数,这些整数的范围在到之间。并且第一个列表是递增顺序排列,第二个列表是递减顺序排列。
输出要求:如果能从两个列表中选出和为的两个数,程序要向标准输出写入“YES”;反之,如果不存在这样的两个数,则输出“NO”。
解题思路
由于两个列表分别是递增和递减的,这一特性为高效解题提供了关键线索,因此可以采用双指针法来解决该问题。
1. 初始化指针:设置两个指针,一个指针(设为)指向第一个递增列表的起始位置,另一个指针(设为)指向第二个递减列表的起始位置。这两个指针用于遍历两个列表中的元素。
2. 计算和并比较:计算两个指针所指向元素的和,即。然后将与目标值进行比较。
情况一:和等于10000:若恰好等于,这就表明找到了满足条件的两个数,此时直接得出结论,程序输出“YES”并结束。
情况二:和小于10000:当小于时,因为第一个列表是递增的,为了使和增大,更接近目标值,将指向第一个列表的指针向后移动一位,即 。这样就可以获取第一个列表中的下一个较大的数,再重新计算和并进行比较。
情况三:和大于10000:要是大于,鉴于第二个列表是递减的,为了让和减小,将指向第二个列表的指针向后移动一位,即 。如此便会获取第二个列表中的下一个较小的数,接着重新计算和并判断。
3. 循环与结果判断:不断重复上述计算和比较的步骤,持续这个过程,直到其中一个指针超出了它所在列表的范围。如果在遍历过程中找到了和为的两个数,程序已经输出“YES”并结束;若遍历结束后仍未找到,那就说明不存在满足条件的两个数,此时程序输出“NO”。
这种双指针法充分利用了列表的有序性,避免了对所有可能组合的暴力枚举,大大提高了算法的效率,将时间复杂度控制在,其中和分别是两个列表的长度。
代码实现
#include<stdio.h> #include<stdlib.h> const int maxN=50000 + 50; int a[maxN],b[maxN]; int main() { int n,m; while(scanf("%d",&n)==1){ int i; for(i=0;i<n;++i) scanf("%d",&a[i]); scanf("%d",&m); for(i=0;i<m;++i) scanf("%d",&b[i]); int p=0,q=0; int ans=0; while(p<n&&q<m){ if(a[p]+b[q]==10000){ ans=1; break; } else if(a[p]+b[q]<10000) ++p; else ++q; } printf("%s\n",ans==0?"NO":"YES"); } return 0; }
代码说明:
1.头文件包含:#include <stdio.h>和#include <stdlib.h>分别引入了标准输入输出库和标准库,使得代码可以使用scanf、printf等函数进行输入输出操作,以及使用stdlib.h中的一些标准函数(虽然在此代码中未用到,但引入是一种常见的编程习惯)。
2.常量和数组定义:const int maxN = 50000 + 50;定义了一个常量maxN,表示数组的最大长度,额外加 50 是为了预留一定的空间,防止数组越界(尽管在本题中不一定需要,但在一些复杂情况下可提供一定的安全性)。int a[maxN], b[maxN];定义了两个整型数组a和b,用于存储输入的两个整数列表。
3.主函数和输入读取:int main()是程序的入口函数。在主函数中,首先定义了变量n和m,用于存储两个数组的长度。然后通过while (scanf("%d", &n) == 1)循环读取输入数据,只要成功读取到一个整数n(表示第一个数组的长度),就进入循环体。在循环体中,使用for循环读取n个整数存入数组a中,接着读取第二个数组的长度m,再使用for循环读取m个整数存入数组b中。
4.双指针查找和结果判断:定义指针p和q,初始值为 0,分别指向数组a和b的起始位置;定义变量ans,初始值为 0,用于标记是否找到满足条件的数对。通过while (p < n && q < m)循环进行双指针查找,在循环体中,根据a[p] + b[q]与 10000 的比较结果移动指针p或q。如果找到和为 10000 的数对,将ans设为 1 并使用break跳出循环。
5.输出结果:最后,使用printf("%s\n", ans == 0? "NO" : "YES");根据ans的值输出相应的结果。如果ans为 0,输出 “NO”;如果ans为 1,输出 “YES”。整个程序通过双指针法高效地解决了从两个有序数组中查找和为 10000 的数对的问题。
- 1
信息
- ID
- 1367
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 17
- 已通过
- 3
- 上传者