原题题面:https://ac.nowcoder.com/acm/contest/33195/I
题目大意:
给定两个整数序列
A
=
[
a
1
,
a
2
…
a
n
]
,
B
=
[
b
1
,
b
2
…
,
b
m
]
A=[a_1,a_2…a_n],B=[b_1,b_2…,b_m]
A=[a1,a2…an],B=[b1,b2…,bm],求是否存在不同的
1
<
=
i
,
j
<
=
n
1<=i,j<=n
1<=i,j<=n,
1
<
=
k
,
l
<
=
m
1<=k,l<=m
1<=k,l<=m,满足
∣
a
i
−
a
j
∣
=
∣
b
k
−
b
l
∣
|a_i-a_j|=|b_k-b_l|
∣ai−aj∣=∣bk−bl∣
分析:
可先将
∣
a
i
−
a
j
∣
=
∣
b
k
−
b
l
∣
|a_i-a_j|=|b_k-b_l|
∣ai−aj∣=∣bk−bl∣转化为
a
i
+
b
l
=
a
j
+
b
k
a_i+b_l=a_j+b_k
ai+bl=aj+bk,所以题目就变成了找是否有
a
i
+
b
l
a_i+b_l
ai+bl的和相同
再读题目,注意到
a
i
,
b
i
a_i,b_i
ai,bi的值均不大于
1
0
7
10^7
107,由于鸽巢原理,其和必定在
V
(
2
∗
1
0
7
)
V(2*10^7)
V(2∗107)次的计算后有重复
(
a
数组内的值均不相同且
b
数组内的值均不相同
)
(a数组内的值均不相同且b数组内的值均不相同)
(a数组内的值均不相同且b数组内的值均不相同)
所以可以去重,再枚举计算
代码:
#include<bits/stdc++.h>
#define LL long long
#define debug -1
using namespace std;
const int max_len=1e6+7;
const int max_val=1e7+7;
const int max_val_with_2=2e7+10;
int a[max_len],b[max_len];
struct Node{
int id[3],val;
};
Node mp[max_val_with_2];
int dx[max_val],dy[max_val];
int idx[max_len],idy[max_len];
template<class T> inline void read(T&x){
char ch,last=' ';
while(!isdigit(ch=getchar())) last=ch;
x=ch^48;
while(isdigit(ch=getchar())) x=(x<<3)+(x<<1)+(ch^48);
if(last=='-') x=-x;
}
int main(){
int n,m,x,cnt,fx1,fx2,fy1,fy2,cnta,cntb;
cnta=cntb=0;
fx1=fx2=fy1=fy2=0;
read(n); read(m);
for(int i=1;i<=n;i++){
read(x);
if(!dx[x]){
a[++cnta]=x; dx[x]=i; idx[cnta]=i;
}else{
fx1=i; fx2=dx[x];
}
}
for(int i=1;i<=m;i++){
read(x);
if(!dy[x]){
b[++cntb]=x; dy[x]=i; idy[cntb]=i;
}else{
fy1=i; fy2=dy[x];
}
}
if(fy1&&fy2&&fx1&&fx2){
printf("%d %d %d %d\n",fx1,fx2,fy1,fy2);
return 0;
}else{
for(int i=1;i<=cnta;i++){
for(int j=1;j<=cntb;j++){
cnt++;
if(cnt>2*max_val){
printf("-1\n");
return 0;
}
x=a[i]+b[j];
if(mp[x].val){
mp[x].val++;
printf("%d %d %d %d\n",idx[i],mp[x].id[1],idy[j],mp[x].id[2]);
return 0;
}else{
mp[x].val++;
mp[x].id[1]=idx[i];
mp[x].id[2]=idy[j];
}
}
}
}
printf("-1\n");
}