码迷,mamicode.com
首页 > 其他好文 > 详细

简单的查找问题

时间:2016-08-02 01:02:20      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

题目地址:http://acm.fafu.edu.cn/problem.php?id=1048

Description:

给定N个正整数和一个正整数P,要求你从中找出两个数字ab使得a + b = p;

Input:

第一行两个数字n,p(n<=10^5;p,n个整数<2^32);第二行n个数字。(有多组测试数据)

Output:

若能找到这两个数字输出Yes,否则输出No.

Sample Input:

3 3

1 2 3

4 2

1 3 2 1

1 5

5

Sample Output:

Yes

Yes

No

 

题目大意是说:能否从给定的n个数中找出两个数ab相加等于p

首先,题目说了是正整数,所以无负数也没有0;所以我们可以吧输入的大于等于p的数据删掉,从而减少后面的搜索次数,然后我们再把这些数字从小到大排列(当然从大到小也行),分别从头和尾开始找这两个数。假设我们把数字存在num[20]数组里,head表示头,tail表示尾(即数组的最后一个元素下标)。

起初head = 0,tail = 19;

(1)如果num[head] + num[tail] 大于 p,说明尾巴的数字太大,应取小一点的值,所以tail--

(2)如果num[head] + num[tail] 小于 p,说明头的数字太小,应取大一点的值,所以head++

(3)如果num[head] + num[tail] 等于 p,说明找到了。

 

以下是源代码:

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long p;
long long num[100005];
int main(void)
{
    int n,i=0,j,flag=0;
    memset(num,0,sizeof(num));
    while(scanf("%d%lld",&n,&p) == 2)
    {
    
        while(n--)
        {
            scanf("%lld",&num[i]);
            if(num[i] >= p) continue;//如果输入的数字大于p,丢掉
            i++;
        }
        n = i;        //n为除去丢弃后剩余的数字个数
        sort(num,num+n);
        for(i=0,j=n-1; i<j;)
        {
            if(num[i]+num[j] > p)       j--;    //大于p说明最右边太大,取小一点,左移
            else if(num[i]+num[j] < p)  i++;    //小于p说明最左边太小,取大一点,右移
            else      {flag = 1;break;}            //相等,找到了 
        }
        if(flag)    printf("Yes\n");
        else        printf("No\n");
        i = flag = 0;
        memset(num,0,sizeof(num));
    }

    return 0;
}
View Code

 

简单的查找问题

标签:

原文地址:http://www.cnblogs.com/Muia/p/5727556.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!