都是用到了求分别在两个数组中的两个数使之和满足某个条件
方法是先排序,然后用两个指针 i,j 分别指向两个数组的头和尾,再调整移动指针。
zoj 3631
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int i,j,a[50],ans,n,m;
int sum1[40000],sum2[40000];
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
while(scanf("%d %d",&n,&m)==2){
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
for(i=0;i<=(1<<(n/2))-1;i++)
for(j=1;j<=n/2;j++)
if(i&(1<<(j-1)))
sum1[i]+=a[j];
int p=n-n/2;
for(i=0;i<=(1<<p)-1;i++)
for(j=1;j<=p;j++)
if(i&(1<<(j-1)))
sum2[i]+=a[j+n/2];
sort(sum1,sum1+(1<<(n/2)));
sort(sum2,sum2+(1<<p));
ans=0;
for(i=0,j=(1<<p)-1;i<(1<<(n/2))&&j>=0;)
if(sum1[i]+sum2[j]<=m){
ans=max(ans,sum1[i]+sum2[j]);
i++;
}
else
j--;
printf("%d\n",ans);
}
}
hdu 4334
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 a[10][201],sum2[50010],sum1[50010];
int main(){
int t,T,i,j,n,k1,k2,flag,kk,p,q;
__int64 tem;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d",&n);
for(i=1;i<=5;i++){
for(j=1;j<=n;j++)
scanf("%I64d",&a[i][j]);
}
sort(a[5]+1,a[5]+1+n);
kk=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
sum1[kk++]=a[1][i]+a[2][j];
sort(sum1,sum1+kk);
k1=unique(sum1,sum1+kk)-sum1;
kk=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
sum2[kk++]=a[3][i]+a[4][j];
sort(sum2,sum2+kk);
k2=unique(sum2,sum2+kk)-sum2;
flag=0;
for(i=1;i<=n&& !flag;i++){
for(p=0,q=k2-1;p<k1 && q>=0;){
if(sum1[p]+sum2[q]+a[5][i]==0){
flag=1;
break;
}
else if(sum1[p]+sum2[q]+a[5][i]>=0)
q--;
else
p++;
}
}
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
}
hdu 4334 也可hash
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef __int64 int64;
#define inf 100007
int64 a[10][201],sum1[50010];//
int head[100010],cnt;
struct point{
int64 real;//
int next;
}edge[50010];
void add(int64 tem){ //
int64 hash=tem%inf; // 先取余 !!!!!!!!
if(hash<0)
hash+=inf;
for(int i=head[hash];i!=-1;i=edge[i].next){
if(tem==edge[i].real)
return;
}
edge[cnt].real=tem;
edge[cnt].next=head[hash];
head[hash]=cnt++;
}
int query(int64 tem){
int64 hash=(-tem)%inf;
if(hash<0)
hash+=inf;
for(int i=head[hash];i!=-1;i=edge[i].next){
if((-tem)==edge[i].real){
return 1;
}
}
return 0;
}
int main(){
int t,T,i,j,k,n,k1,flag,kk;
scanf("%d",&T);
for(t=1;t<=T;t++){
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d",&n);
for(i=1;i<=5;i++){
for(j=1;j<=n;j++)
scanf("%I64d",&a[i][j]);//
}
kk=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
add(a[1][i]+a[2][j]);
flag=0;
for(i=1;i<n && !flag;i++)
for(j=1;j<=n && !flag;j++)
for(k=1;k<=n && !flag;k++)
if(query(a[3][i]+a[4][j]+a[5][k])){
flag=1;
break;
}
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
}