Trouble&&http://acm.hdu.edu.cn/showproblem.php?pid=4334

探讨了5-sum问题的解决方法,通过使用Hash表优化算法,将原本五层循环的暴力搜索降低到三层循环,有效提升了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Problem Description
Hassan is in trouble. His mathematics teacher has given him a very difficult problem called 5-sum. Please help him.
The 5-sum problem is defined as follows: Given 5 sets S_1,...,S_5 of n integer numbers each, is there a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0?

Input
First line of input contains a single integer N (1≤N≤50). N test-cases follow. First line of each test-case contains a single integer n (1<=n<=200). 5 lines follow each containing n integer numbers in range [-10^15, 1 0^15]. I-th line denotes set S_i for 1<=i<=5.

Output
For each test-case output "Yes" (without quotes) if there are a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0, otherwise output "No".

Sample Input
2 2 1 -1 1 -1 1 -1 1 -1 1 -1 3 1 2 3 -1 -2 -3 4 5 6 -1 3 2 -4 -10 -1

Sample Output
No Yes
题意:给你5行数,问你是不是存在这一组数,在每行取一个,使得所求的和为0,
思路:如果直接暴力,五成for循环肯定会挂掉,,这里可以用hash表优化成三层for循环,,
AC代码:
#include<iostream>
#include<string.h>
#include<string>
#define N 100005
using namespace std;
__int64 aa[5][205];
__int64 Hash[N];
bool flag[N];
 int _Hash(__int64 num)
{
	int t=num%N;
	if(t<0) t+=N;
	while(flag[t]&&Hash[t]!=num)  t=(t+1)%N;
	return t;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(flag,false,sizeof(flag));
		int n;
		scanf("%d",&n);
		for(int i=0;i<5;i++){
			for(int j=0;j<n;j++)
				scanf("%I64d",&aa[i][j]);
		}
		memset(flag,0,sizeof(flag));
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
					__int64 num=-(aa[0][i]+aa[1][j]);
				     int pos=_Hash(num);
					 Hash[pos]=num;
					 flag[pos]=true;
				}
			 bool fflag=false;
			 for(int i=0;i<n;++i)
				 for(int j=0;j<n;++j)
					 for(int k=0;k<n;++k)
					 {
						 __int64 num=(aa[2][i]+aa[3][j]+aa[4][k]);
						 int pos=_Hash(num);
						 if(flag[pos]) {fflag=true;i=j=n;break;}
					}
					 if(fflag) printf("Yes\n");
					 else printf("No\n");
	}return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值