Codeforces Round #707 (Div. 2) C. Going Home

题目 : 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(n1)n对组合,从这 ( n − 1 ) ∗ n 2 {(n-1)*n \over 2} 2(n1)n对组合中找到两对相同的,再在这些组合中组合匹配一次,最后的时间复杂度为 O ( N 4 ) O(N^4) O(N4),超时超得实在不能再超了。


再看一遍题目,发现题目还有一个限制条件 a i < = 2.5 ∗ 1 0 6 a_i<=2.5*10^6 ai<=2.5106,那么任意两个序列中的数相加,其和不超过5e6,所以上面可以进行优化:用一个大小为5e6的p数组去标记每个和是否已经出现过,出现第二次,则表明该和已经出现过,题目满足,输出”YES",时间复杂度为 O ( N 2 ) O(N^2) O(N2),但仍然会超时

更进一步分析,因为和最大为5e6,也就是说最多只会又5e6个数作为和,而组合 ( n − 1 ) ∗ n 2 {(n-1)*n \over 2} 2(n1)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";
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值