Codeforces Round #661 (Div. 3)

Codeforces Round #661 (Div. 3) 传送门

A - Remove Smallest

Description

You are given the array a consisting of n positive (greater than zero) integers.
In one move, you can choose two indices i and j (i≠j) such that the absolute difference between ai and aj is no more than one (|ai−aj|≤1) and remove the smallest of these two elements. If two elements are equal, you can remove any of them (but exactly one).
Your task is to find if it is possible to obtain the array consisting of only one element using several (possibly, zero) such moves or not.
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 length of a. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤100), where ai is the i-th element of a.

Output

For each test case, print the answer: “YES” if it is possible to obtain the array consisting of only one element using several (possibly, zero) moves described in the problem statement, or “NO” otherwise.

input

5
3
1 2 2
4
5 5 5 5
3
1 2 4
4
1 3 4 4
1
100

output

YES
YES
NO
NO
YES

Note

In the first test case of the example, we can perform the following sequence of moves:
choose i=1 and j=3 and remove ai (so a becomes [2;2]);
choose i=1 and j=2 and remove aj (so a becomes [2]).
In the second test case of the example, we can choose any possible i and j any move and it doesn’t matter which element we remove.
In the third test case of the example, there is no way to get rid of 2 and 4.

题目大意

要我们对一个数组进行操作,选取两个值进行操作,若差值的绝对值<=1,则删除两个值中较小的一个,若两个数相同,就删除任意一个
若最终能使数组只剩下一个元素就输出“YES”否则输出“NO”

Code
#include
#include
#include
#include
using namespace std;
int a[100];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int cnt = 0;
		int n;
		cin>>n;
		for(int i = 0 ; i < n ; i++)
		{
				cin>>a[i];
		}
		if( n == 1 )
		{
			cout<<"YES"<<endl;
		}else
		{
			sort(a,a+n);
			vector<int>v(a,a+n);
			int len = v.size();
			int flag = 0;
			for(int i = 0 ; i < n-1 ; i++)
			{
				int key = v[i];
				for(int j = i+1 ; j < n ; j++)
				{
					int tmp = abs(key - v[j]);
					if(tmp <= 1 && v[i] != -1)
					{
						v[i] = -1;
						len --;
					}
					if(len == 1)
					{
						flag = 1;
						break;
					}
				}
			}
			if(flag == 1)
			{
				cout<<"YES"<<endl;
			}else
			{
				cout<<"NO"<<endl;
			}
		}
	}
	return 0;
}

B - Gifts Fixing

Description

You have n gifts and you want to give all of them to children. Of course, you don’t want to offend anyone, so all gifts should be equal between each other. The i-th gift consists of ai candies and bi oranges.
During one move, you can choose some gift 1≤i≤n and do one of the following operations:

  • eat exactly one candy from this gift (decrease ai by one);
  • eat exactly one orange from this gift (decrease bi by one);
  • eat exactly one candy and exactly one orange from this gift (decrease both ai and bi by one).

Of course, you can not eat a candy or orange if it’s not present in the gift (so neither ai nor bi can become less than zero).
As said above, all gifts should be equal. This means that after some sequence of moves the following two conditions should be satisfied: a1=a2=⋯=an and b1=b2=⋯=bn (and ai equals bi is not necessary).
Your task is to find the minimum number of moves required to equalize all the given gifts.
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 gifts. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤109), where ai is the number of candies in the i-th gift. The third line of the test case contains n integers b1,b2,…,bn (1≤bi≤109), where bi is the number of oranges in the i-th gift.

Output

For each test case, print one integer: the minimum number of moves required to equalize all the given gifts.

input

5
3
3 5 6
3 2 3
5
1 2 3 4 5
5 4 3 2 1
3
1 1 1
2 2 2
6
1 1000000000 1000000000 1000000000 1000000000 1000000000
1 1 1 1 1 1
3
10 12 8
7 5 4

output

6
16
0
4999999995
7

Note

In the first test case of the example, we can perform the following sequence of moves:
choose the first gift and eat one orange from it, so a=[3,5,6] and b=[2,2,3];
choose the second gift and eat one candy from it, so a=[3,4,6] and b=[2,2,3];
choose the second gift and eat one candy from it, so a=[3,3,6] and b=[2,2,3];
choose the third gift and eat one candy and one orange from it, so a=[3,3,5] and b=[2,2,2];
choose the third gift and eat one candy from it, so a=[3,3,4] and b=[2,2,2];
choose the third gift and eat one candy from it, so a=[3,3,3] and b=[2,2,2].


题目大意

要我们对两个数组进行修改,直到所有元素都相同,修改方式如题所说的三种方式,求数组相同时,操作的最少次数

解题思路

贪心思维,首先我们把每个数组的最小值拿出来,因为要变到整个数组的元素都相同就是变到与数组的最小值相同,然后每个数组对应的减去它的最小值,这个操作我们会得到 第 i 个元素 变到与最小值所需要的次数,然后我们求一个max,看看哪边需要的操作多,让 ans 加上操作数最多的,因为操作 3 是对两个数组进行操作的,假设 ai 变到 mina 需要 3次,bi 变到 minb 需要1次,那么得到的max = 3,3次操作中兼顾 bi 所以应该有一次是操作 3 的两边都操作,然后才是单独一边的对 ai 进行操作,以此类推,最后得到的 ans 就是操作的最少次数


Code
#include
#include
using namespace std;
typedef long long ll;
struct Git
{
	int x;
	int y;
}gift[1000];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;

		int mina = INT_MAX;
		for(int i = 0 ; i < n ; i++)
		{
			cin>>gift[i].x;
			mina = min(gift[i].x,mina);
		}

		int minb = INT_MAX;
		for(int i = 0 ; i < n ; i++)
		{
			cin>>gift[i].y;
			minb = min(gift[i].y,minb);
		}
		ll ans = 0;//爆 int 所以要用 long long
		for(int i = 0 ; i < n ; i++)
		{
			ans += (1ll)*max(gift[i].x - mina,gift[i].y - minb);
		}
		cout<<ans<<endl;
	}
	return 0;
}

C - Boats Competition

Description

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.

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.


题目大意

n个人参加划船比赛,每个人的重量是 wi,每个队伍有两人,所有的队伍的总重量都应为 s ,每个人有且仅有一次分配机会,即一个人只能在一支队伍,问当 s 为最优时,队伍数量最多是多少

解题思路

数据比较小,而且两两相加封顶的两数之和就是n + n,我们直接暴力枚举所有可能的 s 值,然后两两相加判断是否与 s 相等然后记录队伍的数量,并对成队的两个做标记,在进去下一个可能的 s 值之前把当前的 ans 更新为最大即可


Code
#include
#include
#include
using namespace std;
const int maxn = 200;
int w[maxn];
int vis[maxn];
int Team = 0;
int ans = 0;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		memset(vis,-1,sizeof(vis));
		memset(w,0,sizeof(w));
		ans = 0;
		int n;
		cin>>n;
		for(int i = 0 ; i < n ; i++)
		{
			cin>>w[i];
		}
		int maxw = n+n;
		int minw = 1;
		for(int i = minw ; i <= maxw ; i++)//枚举所有可能的 s
		{
			for(int j = 0 ; j < n-1 ; j++)
			{
				if(vis[j] != 1)
				{
					for(int k = j+1 ; k < n ; k++)
					{
						if(vis[k] != 1)
						{
							if(w[j] + w[k] == i)
							{
								vis[k] = 1;//他们两个人组在一起
								vis[j] = 1;
								Team ++;//当可能的 s 为 i 时有多少队伍
								break;//当前的j 和 k 失去用处,跳出进入下一个 j
							}
						}
					}
				}
			}
			ans = max(ans,Team);
			Team = 0;memset(vis,-1,sizeof(vis));
		}
		cout<<ans<<endl;
	}
	return 0;
}

你可能感兴趣的:(Codeforces,Round,贪心算法)