标签:
题目地址:http://acm.fafu.edu.cn/problem.php?id=1048
Description:
给定N个正整数和一个正整数P,要求你从中找出两个数字a,b使得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个数中找出两个数a,b相加等于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; }
标签:
原文地址:http://www.cnblogs.com/Muia/p/5727556.html