Equal Sums

目录

题目总览

思路

简述题意

具体实现

参考代码

原题链接:CF988C Equal Sums


题目总览

# Equal Sums

## 题面翻译

给定 $n$ 个长度不一定相同的序列,你要找到其中两个序列,使得两个序列都删去他们中的一个数后这两个序列的和相同。

无解输出 `NO`,否则第一行输出 `YES`,第二行输出其中一个序列的编号及删除的数在这个序列中的编号,第三行输出另一个序列的编号及删除的数在这个序列中的编号。如有多解可以输出任何一个。

## 题目描述

You are given $ k $ sequences of integers. The length of the $ i $ -th sequence equals to $ n_i $ .

You have to choose exactly two sequences $ i $ and $ j $ ( $ i \ne j $ ) such that you can remove exactly one element in each of them in such a way that the sum of the changed sequence $ i $ (its length will be equal to $ n_i - 1 $ ) equals to the sum of the changed sequence $ j $ (its length will be equal to $ n_j - 1 $ ).

Note that it's required to remove exactly one element in each of the two chosen sequences.

Assume that the sum of the empty (of the length equals $ 0 $ ) sequence is $ 0 $ .

## 输入格式

The first line contains an integer $ k $ ( $ 2 \le k \le 2 \cdot 10^5 $ ) — the number of sequences.

Then $ k $ pairs of lines follow, each pair containing a sequence.

The first line in the $ i $ -th pair contains one integer $ n_i $ ( $ 1 \le n_i < 2 \cdot 10^5 $ ) — the length of the $ i $ -th sequence. The second line of the $ i $ -th pair contains a sequence of $ n_i $ integers $ a_{i, 1}, a_{i, 2}, \dots, a_{i, n_i} $ .

The elements of sequences are integer numbers from $ -10^4 $ to $ 10^4 $ .

The sum of lengths of all given sequences don't exceed $ 2 \cdot 10^5 $ , i.e. $ n_1 + n_2 + \dots + n_k \le 2 \cdot 10^5 $ .

## 输出格式

If it is impossible to choose two sequences such that they satisfy given conditions, print "NO" (without quotes). Otherwise in the first line print "YES" (without quotes), in the second line — two integers $ i $ , $ x $ ( $ 1 \le i \le k, 1 \le x \le n_i $ ), in the third line — two integers $ j $ , $ y $ ( $ 1 \le j \le k, 1 \le y \le n_j $ ). It means that the sum of the elements of the $ i $ -th sequence without the element with index $ x $ equals to the sum of the elements of the $ j $ -th sequence without the element with index $ y $ .

Two chosen sequences must be distinct, i.e. $ i \ne j $ . You can print them in any order.

If there are multiple possible answers, print any of them.

## 样例 #1

### 样例输入 #1

```
2
5
2 3 1 3 2
6
1 1 2 2 2 1
```

### 样例输出 #1

```
YES
2 6
1 2
```

## 样例 #2

### 样例输入 #2

```
3
1
5
5
1 1 1 1 1
2
2 3
```

### 样例输出 #2

```
NO
```

## 样例 #3

### 样例输入 #3

```
4
6
2 2 2 2 2 2
5
2 2 2 2 2
3
2 2 2
5
2 2 2 2 2
```

### 样例输出 #3

```
YES
2 2
4 1
```

## 提示

In the first example there are two sequences $ [2, 3, 1, 3, 2] $ and $ [1, 1, 2, 2, 2, 1] $ . You can remove the second element from the first sequence to get $ [2, 1, 3, 2] $ and you can remove the sixth element from the second sequence to get $ [1, 1, 2, 2, 2] $ . The sums of the both resulting sequences equal to $ 8 $ , i.e. the sums are equal.

思路

简述题意

在 n 个长度不一定相同的序列中任选两个序列,两个序列都删去他们中的一个数,使得这两个序列的和相同。


我们按顺序依次去看每一个序列,对于第 i 个序列,因为现在允许我们删掉一个数字,我们可以先把所有数字求和,再依次枚举每个数字,从总和中减掉,这样我们可以得到所有可能的和。

这时候去找一下,前面有没有哪个序列已经产生过这个和,如果之前出现过,它们两个就匹配形成答案。如果没有出现过,那么就把这个和记下来,等着后面有没有来匹配我的。

这里就形成了一个“记录”的需求,需要记录和以及这个和出现在第几个序列里,以及这个和是删掉了哪个数形成的。并且我们需要根据和进行快速的查询。这里正好发现 map 是可以满足需求的。

具体实现

首先用定义一个结构体和一个 map :

struct Node 
{
    int bh, er;
};
map<int, Node> m;

其中,结构体中的 bh 表示目前是第几个序列, er 表示这个序列中我们要删掉哪个数字。然后用删掉数字以后的和来当 map 的 key ,来存储这个和与结构体。

接下来就是遍历每个序列,再遍历每个要被删掉的数,计算出现在的和。用这个和到 map 里面去查询,如果之前出现过,则输出答案,否则将这个和记录到 map 里。具体可以看代码。

参考代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 200005;

struct node
{
	int bh;
	int er;
};

int a[N];
map <int, node> mp;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	int k, n, h = 0;
	cin>>k;
	
	for(int i = 1; i <= k; i++)
	{
		memset(a, 0, sizeof(a));
		cin>>n;
		
		for(int j = 1; j <= n; j++)
		{
			cin>>a[j];
			h += a[j];
		}
		
		for(int j = 1; j <= n; j++)
		{
			int erase = h - a[j];
			
			if(mp.find(erase) != mp.end() && mp[erase].bh != i)
			{
				cout<<"YES\n";
				cout<<mp[erase].bh<<" "<<mp[erase].er<<"\n";
				cout<<i<<" "<<j;
				return 0;
			}
			else
			{
				mp[erase].bh = i;
				mp[erase].er = j;
			}
		}
		h = 0;
	}
	
	cout<<"NO";
	
	return 0;
}

原题链接:CF988C Equal Sums


第一篇附带思路的博文,大家喜欢的点个关注!之后持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学废c++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值