51nod 1267 4个数和为0

来源:互联网 发布:ui设计php 编辑:程序博客网 时间:2024/04/29 12:29

1267 4个数和为0
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
 收藏
 取消关注
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
Input
第1行,1个数N,N为数组的长度(4 <= N <= 1000)第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。
Input示例
5-11-524
Output示例
Yes

题解一:

1.首先对输入序列进行升序排序(因为后面需要进行二分搜索和优化)

2.设需要判断的是a[i] + a[j] + a[k] +a[l] 是否等于0,第一层循环遍历i,第二层循环遍历j,第三层循环遍历k,最后我们用二分搜索a[l](即0 - (a[i] + a[j] + a[k]) 是否存在于a[K+1 ]~a[n-1]中。

然后就超时了微笑,两组数据没过。。。

优化:在每层for循环里加了个判断条件,就像代码中写的那样。

如果a[i] > 0,直接退出i循环, 因为0<a[i]<=a[j] <=a[k] <=a[l],四数相加必定大于0。

如果a[i] + a[j] > 0,直接退j循环,因为此时a[i]<=0,a[j]必然大于a[i]的绝对值,即a[j] > 0。故0< a[j] <=a[k] <=a[l],四数相加必定大于0。

如果a[i] + a[j] + a[k] > 0,直接退k循环,因为此时a[i] + a[j]<=0,a[k]必然大于(a[i] + a[j])的绝对值,即a[k]>0。故0<a[k]<=a[l],四数相加必定大于0。

然后AC了,效率榜貌似排了倒数


代码:

#include <stdio.h>#include <stdlib.h>int binarySearch(int array[], int obj, int low, int high){int mid;mid = (low + high) / 2;if (low <= high){if (obj < array[mid]){return binarySearch(array, obj, low, mid - 1);}else if (obj > array[mid]){return binarySearch(array, obj, mid + 1, high);}else{return mid;}}elsereturn -1;}int cmp(const void*a, const void* b){return *(int*)a - *(int*)b;}int main(){int n, i, j, k, a[1005];scanf("%d", &n);for (i = 0; i < n; i++){scanf("%d", &a[i]);}qsort(a, n, sizeof(int), cmp);int tag = 0;for (i = 0; (i < n - 3) && (a[i] <= 0); i++){for (j = i + 1; (j < n - 2) && (a[i] + a[j] <= 0); j++){for (k = j + 1; (k < n - 1) && (a[i] + a[j] + a[k ] <= 0); k++){if (binarySearch(a, 0 - (a[i] + a[j] + a[k]), k + 1, n - 1) != -1){tag = 1;printf("Yes\n");return 0;}}}}if (tag == 0){printf("No\n");}return 0;}


题解2:用hash做的??



贴一发大佬代码:

#include<stdio.h>#define rep(i,a,b) for(int i=a;i<=b;i++)#define mod 1000007int N;int hash_table[1000010],hnum;struct node{int val;int nxt;}a[2002000];int b[1010];void init(){rep(i,0,mod)hash_table[i]=-1;hnum=0;}int insert_hash(int x){int h=(int)((1uLL*x*x)%mod);hnum++;a[hnum].val=x;a[hnum].nxt=hash_table[h];hash_table[h]=hnum;}int check_hash(int x){int h=(int)((1uLL*x*x)%mod);for(int i=hash_table[h];i>0;i=a[i].nxt){if(a[i].val==x)return 1;}return 0;}main(){scanf("%d",&N);rep(i,1,N)scanf("%d",&b[i]);init();int flag=0;rep(i,3,N-1){rep(j,1,i-2)insert_hash(b[i-1]+b[j]);rep(j,i+1,N){if(check_hash(-(b[i]+b[j]))){flag=1;break;}}if(flag)break;}if(flag){printf("Yes\n");}else printf("No\n");}


原创粉丝点击