Codeforces Round #669 (Div. 2) A,B题解

A. Ahahahahahahahaha

Alexandra has an even-length array a, consisting of 0s and 1s. The elements of the array are enumerated from 1 to n. She wants to remove at most n2 elements (where n — length of array) in the way that alternating sum of the array will be equal 0 (i.e. a1−a2+a3−a4+…=0). In other words, Alexandra wants sum of all elements at the odd positions and sum of all elements at the even positions to become equal. The elements that you remove don’t have to be consecutive.

For example, if she has a=[1,0,1,0,0,0] and she removes 2nd and 4th elements, a will become equal [1,1,0,0] and its alternating sum is 1−1+0−0=0.

Help her!

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤10^3). Description of the test cases follows.

The first line of each test case contains a single integer n (2≤n≤10^3, n is even) — length of the array.

The second line contains n integers a1,a2,…,an (0≤ai≤1) — elements of the array.

It is guaranteed that the sum of n over all test cases does not exceed 10^3.

Output

For each test case, firstly, print k (n/2≤k≤n) — number of elements that will remain after removing in the order they appear in a. Then, print this k numbers. Note that you should print the numbers themselves, not their indices.

We can show that an answer always exists. If there are several answers, you can output any of them.

Example

input

4
2
1 0
2
0 0
4
0 1 1 1
4
1 1 0 0

output

1
0
1
0
2
1 1
4
1 1 0 0

Note

In the first and second cases, alternating sum of the array, obviously, equals 0.

In the third case, alternating sum of the array equals 1−1=0.

In the fourth case, alternating sum already equals 1−1+0−0=0, so we don’t have to remove anything.
这道题的
题目意思就是给你一个n个数的序列,让你去删除不大于n/2的数,使得得到的序列奇数和与偶数和一样。
这道题我的思路就是0和1的个数必定有有一个大于等于n/2,那么我们只需要全部保留个数多的那个就可以了。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int num0=0;
		int num1=0;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			if(a[i]==1)num1++;
			else num0++;
		}
	    if(num1>num0){
	    	if(num1%2==0){
	    		cout<<num1<<endl;
	    		for(int i=1;i<=num1;i++){
	    			printf("%d%c",1,i==num1?'\n':' ');
				}
			}
			else {
				cout<<num1-1<<endl;
				for(int i=1;i<=num1-1;i++){
					printf("%d%c",1,i==num1-1?'\n':' ');
				}
			}
		}
		else {
			cout<<num0<<endl;
			for(int i=1;i<=num0;i++){
				printf("%d%c",0,i==num0?'\n':' ');
			}
		}
	}
} 

B. Big Vova

Alexander is a well-known programmer. Today he decided to finally go out and play football, but with the first hit he left a dent on the new Rolls-Royce of the wealthy businessman Big Vova. Vladimir has recently opened a store on the popular online marketplace “Zmey-Gorynych”, and offers Alex a job: if he shows his programming skills by solving a task, he’ll work as a cybersecurity specialist. Otherwise, he’ll be delivering some doubtful products for the next two years.

You’re given n positive integers a1,a2,…,an. Using each of them exactly at once, you’re to make such sequence b1,b2,…,bn that sequence c1,c2,…,cn is lexicographically maximal, where ci=GCD(b1,…,bi) - the greatest common divisor of the first i elements of b.

Alexander is really afraid of the conditions of this simple task, so he asks you to solve it.

A sequence a is lexicographically smaller than a sequence b if and only if one of the following holds:

a is a prefix of b, but a≠b;
in the first position where a and b differ, the sequence a has a smaller element than the corresponding element in b.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤10^3). Description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤10^3) — the length of the sequence a.

The second line of each test case contains n integers a1,…,an (1≤ai≤10^3) — the sequence a.

It is guaranteed that the sum of n over all test cases does not exceed 10^3.

Output

For each test case output the answer in a single line — the desired sequence b. If there are multiple answers, print any.

Example

input
7
2
2 5
4
1 8 2 3
3
3 8 9
5
64 25 75 100 50
1
42
6
96 128 88 80 52 7
5
2 4 8 16 17

output

5 2
8 2 1 3
9 3 8
100 50 25 75 64
42
128 96 80 88 52 7
17 2 4 8 16

Note

In the first test case of the example, there are only two possible permutations b — [2,5] and [5,2]: for the first one c=[2,1], for the second one c=[5,1].

In the third test case of the example, number 9 should be the first in b, and GCD(9,3)=3, GCD(9,8)=1, so the second number of b should be 3.

In the seventh test case of the example, first four numbers pairwise have a common divisor (a power of two), but none of them can be the first in the optimal permutation b.

这道题题目意思有点难理解,读了半天,大致意思是给你有n个数序列a,让你去构造一个序列b,使得序列c的最大,c的第i个元素等于gcd(b1,b2,……,bi)。
序列大小判断跟字符串的大小判断差不多,这里就不说了。
我的思路是b的第一个元素一定是a中最大的元素,b的第一个元素确认,GCD=b1,然后去遍历a数组去找与GCD的最小公因数最大,最大的就是b2,此时GCD=gcd(b1,b2),这样下去,如果GCD=1,那么说明剩下的数这么输出都没事,就去遍历一遍将为加入的数输出就可以了。
代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int b[maxn];
bool com(int a,int b){
	return a>b;
}
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
int main(){
	int t;
	cin>>t;
	while(t--){
		memset(b,0,sizeof b);
		int n;
		cin>>n;
		int cnt=n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		sort(a+1,a+1+n,com);
		b[1]=1;
		cout<<a[1]<<" ";
		int max1=1;
		int gcd1=a[1];
		int i1=1;
		cnt=cnt-1;
		for(int i=1;i<n;i++){
			max1=1;
			for(int j=1;j<=n;j++){
				if(gcd(gcd1,a[j])>max1&&!b[j]){
					max1=gcd(gcd1,a[j]);
					i1=j;
				}
			}
			b[i1]=1;
			gcd1=max1;
			if(max1==1){
				for(int j=1;j<=n;j++){
				    if(!b[j]){
					    printf("%d",a[j]);
				         if(cnt==1)cout<<endl;
			             else{cnt--;cout<<" ";} 
				}
				}
				break;
			}
			else {printf("%d",a[i1]);
			if(cnt==1)cout<<endl;
			else {cnt--;cout<<" ";} 
			}
		}
	}
}

道阻且长
自己选的路 跪着也要走完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值