Equal Sums CodeForces - 988C

小A有 n 个整数数列 a1,a2,…an ,每个数列的长度为li。

请你找出两个编号不同的数列,并从这两个数列中各恰好删除一个数,使得这两个数列的和相等。

【输入格式】

输入格式如下:
n
l1
a1-1 a1-2 … a1-l1
l2
a2-1 a2-2 … a2-l2

ln
an-1 an-2 … an-ln

【输出格式】

如果不存在解,请在第一行输出"NO"(不含引号)。
否则,请按如下格式输出:
第一行输出"YES"(不含引号),
第二行输出两个整数 i,x ,表示选择的第一个数列编号为 i ,并删除其中的第 x 个数,
第三行输出两个整数 j,y ,表示选择的第二个数列编号为 j ,并删除其中的第 y 个数。

若存在多解,你可以输出任何一个。

【样例输入/输出】

编号 输入 输出


2 3 1 3 2 

1 1 2 2 2 1 
YES 
2 6 
1 2 




1 1 1 1 1 

2 3 
NO 


2 2 2 2 2 2 

2 2 2 2 2 

2 2 2 

2 2 2 2 2 
YES 
2 2 
4 1 

【样例解释】

请自行计算。

【数据范围】

对于所有测试数据:
2 ≤ n ≤ 2×105
1 ≤ li < 2×105
∑li ≤ 2×105
-104 ≤ ai-j ≤ 104

一遇到这种的题目就不是很会,今天写写这个题目留作纪念,感觉解法很新颖。就是一个大暴力,将每个数据都判断一遍。那要如何进行判断呢?既然题目说的是任意 两个 序列各自删除 一个 值,使得剩下的数据和相同 ,对于这种的,我先将这一个序列总的和求出来,然后再进行 每一个元素的判断,这里是如何怕判断的呢?我说一下,我们就可以用stl 容器进行搜索,判断当前如果删除这个数据,剩下的和是否出现过,如果出现过(可能一行中有相同的元素,我们也需要特判一下 continue ),然后就可以了,输出在哪个序列和哪个位置,我们也需要 map 进行标记,输出相关数据的信息。使用 map 进行模拟。

#include<iostream>
using namespace std;
#include<bits/stdc++.h> 
const int maxn=200005;
typedef long long ll;
typedef pair<ll,ll> p;

map<ll,ll>hang,lie,he;
vector<ll>a[maxn];


int main()
{
	ll n;
	cin>>n;
	
	ll num;
	for(int i=1;i<=n;i++)
	{
		ll sum=0;
		ll shu;
		cin>>num;
		for(int j=0;j<num;j++)
		{
			cin>>shu;
			a[i].push_back(shu);
			sum+=shu;
		}
		
		for(int j=0;j<num;j++)
		{
			ll t=sum-a[i][j];
			if(he[t])
			{
				if(hang[t]==i)
					continue;
				else
				{
					cout<<"YES"<<endl;
					cout<<i<<' '<<j+1<<endl;
					cout<<hang[t]<<' '<<lie[t]<<endl;
					return 0;
				}
				
		
			}
			else
			{
				he[t]=1;
				hang[t]=i;
				lie[t]=j+1;
			}
				
		}
		
	}
	cout<<"NO"<<endl;
	return 0;
}

  思路很新颖 

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89003417