题目 : https://codeforces.com/contest/1501/problem/C
一、题意
题目就是在一个给定整数序列中(无序)求是否存在满足 a x a_x ax+ a y a_y ay= a z a_z az+ a w a_w aw的四个互不不相同下标x,y,z,w。
二、题解
首先序列长度N的最大规模为2e5,那么根据排列组合
C
n
2
C_{n}^{2}
Cn2 ,即
(
n
−
1
)
∗
n
2
{(n-1)*n \over 2}
2(n−1)∗n对组合,从这
(
n
−
1
)
∗
n
2
{(n-1)*n \over 2}
2(n−1)∗n对组合中找到两对相同的,再在这些组合中组合匹配一次,最后的时间复杂度为
O
(
N
4
)
O(N^4)
O(N4),超时超得实在不能再超了。
再看一遍题目,发现题目还有一个限制条件
a
i
<
=
2.5
∗
1
0
6
a_i<=2.5*10^6
ai<=2.5∗106,那么任意两个序列中的数相加,其和不超过5e6,所以上面可以进行优化:用一个大小为5e6的p数组去标记每个和是否已经出现过,出现第二次,则表明该和已经出现过,题目满足,输出”YES",时间复杂度为
O
(
N
2
)
O(N^2)
O(N2),但仍然会超时
更进一步分析,因为和最大为5e6,也就是说最多只会又5e6个数作为和,而组合 ( n − 1 ) ∗ n 2 {(n-1)*n \over 2} 2(n−1)∗n必然大于5e6,当n>=3000+(左右,这是个大概的数),组合结果一定大于5e6所以一定会出现答案,最多不过运行5e6次。当n<3000+时, O ( N 2 ) O(N^2) O(N2)不会超时.
代码如下(示例):
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200005
#define M 5000000
using namespace std;
int n,a[N];
pair<int ,pair<int,int> > p[M];
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int x=a[i]+a[j];
p[x].first++;
if(p[x].first==1)
p[x].second.first=i , p[x].second.second=j;
else
{
int z=p[x].second.first, w=p[x].second.second;
if(z!=i&&w!=i&&z!=j&&w!=j)
{
cout<<"YES\n"<<z<<" "<<w<<" "<<i<<" "<<j;
return 0;
}
}
}
cout<<"NO";
}