Codeforces 1399C

C. Boats Competition

time limit per test2 seconds
memory limit per test256 megabytes
input standard input
output standard output
There are n people who want to participate in a boat competition. The weight of the i-th participant is wi. Only teams consisting of two people can participate in this competition. As an organizer, you think that it’s fair to allow only teams with the same total weight.

So, if there are k teams (a1,b1), (a2,b2), …, (ak,bk), where ai is the weight of the first participant of the i-th team and bi is the weight of the second participant of the i-th team, then the condition a1+b1=a2+b2=⋯=ak+bk=s, where s is the total weight of each team, should be satisfied.

Your task is to choose such s that the number of teams people can create is the maximum possible. Note that each participant can be in no more than one team.

You have to answer t independent test cases.

Input

The first line of the input contains one integer t (1≤t≤1000) — the number of test cases. Then t test cases follow.

The first line of the test case contains one integer n (1≤n≤50) — the number of participants. The second line of the test case contains n integers w1,w2,…,wn (1≤wi≤n), where wi is the weight of the i-th participant.

Output

For each test case, print one integer k: the maximum number of teams people can compose with the total weight s, if you choose s optimally.

Example
input
5
5
1 2 3 4 5
8
6 6 6 6 6 6 8 8
8
1 2 2 1 2 1 1 2
3
1 3 3
6
1 1 3 4 2 2
output
2
3
4
1
2

Note

In the first test case of the example, we can reach the optimal answer for s=6. Then the first boat is used by participants 1 and 5 and the second boat is used by participants 2 and 4 (indices are the same as weights).

In the second test case of the example, we can reach the optimal answer for s=12. Then first 6 participants can form 3 pairs.

In the third test case of the example, we can reach the optimal answer for s=3. The answer is 4 because we have 4 participants with weight 1 and 4 participants with weight 2.

In the fourth test case of the example, we can reach the optimal answer for s=4 or s=6.

In the fifth test case of the example, we can reach the optimal answer for s=3. Note that participant with weight 3 can’t use the boat because there is no suitable pair for him in the list.

题目大意:

一共 t 组测试样例,每组输入一个 n 表示一共有n个人,然后第二行输入n 个数,代表第 i 个人的权重,我们需要对其进行两两配对,每个人只能属于一个队伍,队伍的权重等于两人权重之和,求最多可以组成多少对权重相同的队伍。

解题思路:

n = 50,排个序 从2 -> 2 * n 双指针即可,注意一下指针在变换的过程中判断一下当前权重和当前枚举的 s 之间的关系再决定动哪个指针,取最大值即可。(比赛时因为没考虑到指针移动硬是没做出来)

Code:

#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 150;
int g[N], n;
int check(int s)
{
	int res = 0;
	int l = 1, r = n;
	while (l < r)
	{
		if (g[l] + g[r] == s)
		{
			res++;
		    l++, r--;
		}
		else
		{
			if (g[l] + g[r] > s)//我是从大到小排序的,如果大了则右移,调小,反之亦然
				l ++;
			else
				r --;
		}
	}
	return res;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		for (int i = 1; i <= n; i ++)
			cin >> g[i];
		sort(g + 1, g + n + 1, greater<int>() );
		int ans = 0;
		for (int i = 2; i <= 2 * n; i ++)//枚举答案即可
		{
			int r = check(i);
			ans = max(ans, r);
		}
		cout << ans << endl;
	}
	return 0;
}

除此之外还有一个非常巧的方法,就是输入的时候统计次数,枚举 2 -> (s + 1) / 2 的答案,然后一一配对,在代码里说明。

Code2:

#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 150;
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		vector<int > v(n + 1);
		for (int i = 1; i <= n; i ++)
		{
			int s;
			cin >> s;
			v[s]++;
		}
		int ans = 0;
		for (int s = 2; s <= 2 * n; s ++)
		{
			int cp = 0;//表示权重为s 的对数
			for (int i = 1; i < (s + 1) / 2; i ++)
			{
				if (s - i > n)  continue;//特判一下,因为最大是n, >n 则会越界
				cp += min(v[i], v[s - i]);//这里找最小值即为权重为s的对数
			}
			if (s % 2 == 0)  cp += v[s / 2] / 2;//偶数注意一下中间值
			ans = max(ans, cp);
		}
		cout << ans << endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Hayasaka/p/14294156.html