题目:
描述
给出若干个整数,询问其中是否有一对数的和等于给定的数。
输入
共三行:
第一行是整数n(0 < n <= 100,000),表示有n个整数。
第二行是n个整数。整数的范围是在0到10^8之间。
第三行是一个整数m(0 <= m <= 2^30),表示需要得到的和。
输出
若存在和为m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No。
样例输入
4
2 5 1 4
6
样例输出
1 5
解题思路
定义一个标志,默认值为0
把数组按从小到大排序
写一个for循环对数组的每一项进行遍历,在for循环中利用二分查找查找在剩余的每一项中是否有和为给定的数,如果有给标志赋值1,并跳出循环
for循环结束后如果标志值仍然为0,则输出No
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 int f = 0; //标志数 6 7 int main() 8 { 9 int n,m; 10 cin >> n; 11 int num[n]; 12 for(int i = 0; i < n; i++){ 13 cin >> num[i]; 14 } 15 cin >> m; 16 17 sort(num, num + n); //对数组进行升序排序 18 19 for(int i = 0; i < n; i++){ 20 int left = i + 1, right = n; 21 while(left < right){ 22 int mid = (left + right) / 2; 23 //找到给定值输出结果并结束循环 24 if(num[mid] + num[i] == m){ 25 f = 1; 26 cout << num[i] << " " << num[mid] << endl; 27 break; 28 } 29 if(num[i] + num[mid] < m){ 30 left = mid + 1; 31 } 32 else{ 33 right = mid - 1; 34 } 35 } 36 if(f == 1) break; //如果标志为1代表已经输出了需要的结果,无需后续遍历 37 } 38 39 //未找到给定数 40 if(f == 0){ 41 cout << "No" << endl; 42 } 43 44 return 0; 45 }
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_51684823/article/details/129189796
-------------------------------------------------
中间的坑
用血与泪的经历告诉你们这道题的思路orz
1、开始 我是这样想的 从那些数中 找出一个比给定数小一位的数,然后找m-比他小一位的数是否在序列中,但是还要判断比他小一位的数
是否在序列中等诸多问题(orz),然后就wrong了
后来 题解 的方法是将序列按升序排序,从第一位开始,看看m-第一位是否在序列中。。正好与我相反(orz)
然后又wrong了QAQ
2、有个坑 如果 2个数 1 3 给定数为2,那么就会输出1 1,这是不对的,1重复使用了。所以还要判断重复使用。在二分查找的时候,函数的返回值是他的位置
并且找到的这个位置不能等于他正在枚举的数的位置,这样就避免了、、、、
但是 又 wrong了
3、原来 是 移位运算的顺序0-0
l+(r-l)/2 这是我的本意 然后我用了移位运算 l+(r-l)>>1,这样是不对的
因为 (下面贴一大段qwq)
优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。 相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符。 基本的优先级需要记住: 指针最优,单目运算优于双目运算。如正负号。 先乘除(模),后加减。 先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7. 逻辑运算最后计算。果然 我还是又wrong了。。。
4、原来我开始定义的long long 格式化却用的%d。。。。
标签:输出,优先级,运算,int,二分法,wrong,num,定数 From: https://www.cnblogs.com/lmarsy/p/18117345