和为给定数(二分)

07:和为给定数

总时间限制: 
1000ms
内存限制: 
65536kB
描述

给出若干个整数,询问其中是否有一对数的和等于给定的数。

输入
共三行:
第一行是整数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

【思路】

# 结果 时间
14 Accepted 03-28
13 Accepted 03-28
12 Accepted 03-28
11 Time Limit Exceeded 03-28
10 Accepted 03-28
9 Wrong Answer 03-28
8 Time Limit Exceeded 03-28
7 Wrong Answer 03-28
6 Runtime Error 03-28
5 Runtime Error 03-28
4 Runtime Error 03-28
3 Wrong Answer 03-28
2 Compile Error 03-27
1 Wrong Answer 03-27

让爸爸用血与泪的经历告诉你们这道题的思路orz

开始 我是这样想的 从那些数中 找出一个比给定数小一位的数,然后找m-比他小一位的数是否在序列中,但是还要判断比他小一位的数

是否在序列中等诸多问题(orz),然后就wrong了

后来 题解 的方法是将序列按升序排序,从第一位开始,看看m-第一位是否在序列中。。正好与我相反(orz)

然后又wrong了QAQ

有个坑 如果 2个数 1 3 给定数为2,那么就会输出1 1,这是不对的,1重复使用了。所以还要判断重复使用。在二分查找的时候,函数的返回值是他的位置

并且找到的这个位置不能等于他正在枚举的数的位置,这样就避免了、、、、

但是 又 wrong了

原来 是 移位运算的顺序0-0

l+(r-l)/2 这是我的本意 然后我用了移位运算 l+(r-l)>>1,这样是不对的 

因为 (下面贴一大段qwq)

优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。
相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个优先级是从右至左结合的,它们是 单目运算符条件运算符赋值运算符
基本的优先级需要记住:
指针最优,单目运算优于双目运算。如正负号。
先乘除(模),后加减。
先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7.
逻辑运算最后计算。

果然 我还是又wrong了。。。

原来我开始定义的long long 格式化却用的%d。。。。

最后

accepted

end(orz) 

【代码】
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m;
 7 int a[100009];
 8 int   f(int);
 9 int main()
10 {
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++)
13     scanf("%d",&a[i]);
14     scanf("%d",&m);
15     sort(a+1,a+n+1);//排序 
16     for(int i=1;a[i]<=m/2;i++)//枚举m/2前面的数(这样循环次数会少,因为m/2总有一个数满足) 
17     {
18         if(f(m-a[i])&&f(m-a[i])!=i)//能找到这个数并且没有重复使用 
19         {
20             printf("%d %d",a[i],m-a[i]);
21             return 0;
22         }
23     }
24     printf("No");
25     return 0;
26 }
27 int f(int  x)// 返回位置 
28 {
29     int  l=1,r=n,mid;
30     while(l<=r)
31     {
32         mid=l+((r-l)>>1);//>>1是除以2。不用(l+r)/2是为了避免l+r数据过大 
33         if(a[mid]==x)return mid;
34         if(a[mid]<x)l=mid+1;
35         if(a[mid]>x)r=mid-1;
36     }
37     return 0;
38 }

 

转载于:https://www.cnblogs.com/zzyh/p/6633054.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值