第三次习题2020.5.26

A - Sorted Adjacent Differences

You have array of nn

numbers a1,a2,…,ana1,a2,…,an

. Rearrange these numbers to satisfy |a1−a2|≤|a2−a3|≤…≤|an−1−an||a1−a2|≤|a2−a3|≤…≤|an−1−an|

, where |x||x|

denotes absolute value of xx

. It’s always possible to find such rearrangement.Note that all numbers in aa

are not necessarily different. In other words, some numbers of aa

may be same.You have to answer independent tt

test cases.

Input

The first line contains a single integer tt

(1≤t≤1041≤t≤104

) — the number of test cases.The first line of each test case contains single integer nn

(3≤n≤1053≤n≤105

) — the length of array aa

. It is guaranteed that the sum of values of nn

over all test cases in the input does not exceed 105105

.The second line of each test case contains nn

integers a1,a2,…,ana1,a2,…,an

(−109≤ai≤109−109≤ai≤109

).

Output

For each test case, print the rearranged version of array aa

which satisfies given condition. If there are multiple valid rearrangements, print any of them.

Example

Input
2
6
5 -2 4 8 6 5
4
8 1 4 2
Output
5 5 4 6 8 -2
1 2 4 8

题意

 将给出的数列重新排序,排序后数列的连续差的绝对值递增。

思路

将数列排序,从中间向两边输出(区间越来越大绝对值越大)。

代码

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,i,j;
        cin>>n;
        int a[n+1];
        for(i=1;i<=n;i++)cin>>a[i];
        sort(a+1,a+n+1);
        for(i=n/2,j=n/2+1;i>=1||j<=n;i--,j++){
            if(j<=n)cout<<a[j]<<" ";
            if(i>=1)cout<<a[i]<<" ";
        }
        cout<<endl;
    }
}

B - Powered Addition

You have an array aa

of length nn

. For every positive integer xx

you are going to perform the following operation during the xx

-th second: Select some distinct indices i1,i2,…,iki1,i2,…,ik

which are between 11

and nn

inclusive, and add 2x−12x−1

to each corresponding position of aa

. Formally, aij:=aij+2x−1aij:=aij+2x−1

for j=1,2,…,kj=1,2,…,k

. Note that you are allowed to not select any indices at all. You have to make aa

nondecreasing as fast as possible. Find the smallest number TT

such that you can make the array nondecreasing after at most TT

seconds.Array aa

is nondecreasing if and only if a1≤a2≤…≤ana1≤a2≤…≤an

.You have to answer tt

independent test cases.

Input

The first line contains a single integer tt

(1≤t≤1041≤t≤104

) — the number of test cases.The first line of each test case contains single integer nn

(1≤n≤1051≤n≤105

) — the length of array aa

. It is guaranteed that the sum of values of nn

over all test cases in the input does not exceed 105105

.The second line of each test case contains nn

integers a1,a2,…,ana1,a2,…,an

(−109≤ai≤109−109≤ai≤109

).

Output

For each test case, print the minimum number of seconds in which you can make aa

nondecreasing.

Example

Input 3
4
1 7 6 5
5
1 2 3 4 5
2
0 -4
Output
2
0
3

题意

给出一个数组,要求得到一个递增的数组,在第x秒aij可以加上2^x-1。问最短消耗几秒。

思路

遍历找出是否存在递减,找出最大值,判断最大差值,最短需要多少秒,因为2的次方与位数有关。

代码

#include<iostream>
#include<cmath>
using namespace std;
int sum(long long x){
    int count=0;
    while(x){
        count++;
        x>>=1ll;
    }
    return count;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,i;
        cin>>n;
        int a[n+1];
        for(i=1;i<=n;i++)cin>>a[i];
        long long max2=0;
        long long max1=(long long)a[1];
        for(i=2;i<=n;i++){
            max1=max(max1,(long long)a[i]);
            if(max1>a[i])max2=max(max2,max1-(long long)a[i]);
        }
        if(max2==0)cout<<0<<endl;
        else{
            cout<<sum(max2)<<endl;
        }
    }
}

C - Middle Class

Many years

ago Berland was a small country where only nn

people lived. Each person had some savings: the ii

-th one had aiai

burles.The government considered a person as wealthy if he had at least xx

burles. To increase the number of wealthy people Berland decided to carry out several reforms. Each reform looked like that: the government chooses some subset of people (maybe all of them); the government takes all savings from the chosen people and redistributes the savings among the chosen people equally. For example, consider the savings as list [5,1,2,1][5,1,2,1]
if the government chose the 11

-st and the 33

-rd persons then it, at first, will take all 5+2=75+2=7

burles and after that will return 3.53.5

burles to the chosen people. As a result, the savings will become [3.5,1,3.5,1][3.5,1,3.5,1]

.A lot of data was lost from that time, so we don’t know how many reforms were implemented and to whom. All we can do is ask you to calculate the maximum possible number of wealthy people after several (maybe zero) reforms.InputThe first line contains single integer TT

(1≤T≤10001≤T≤1000

) — the number of test cases.Next 2T2T

lines contain the test cases — two lines per test case. The first line contains two integers nn

and xx

(1≤n≤1051≤n≤105

, 1≤x≤1091≤x≤109

) — the number of people and the minimum amount of money to be considered as wealthy.The second line contains nn

integers a1,a2,…,ana1,a2,…,an

(1≤ai≤1091≤ai≤109

) — the initial savings of each person.It’s guaranteed that the total sum of nn

doesn’t exceed 105105

.OutputPrint TT

integers — one per test case. For each test case print the maximum possible number of wealthy people after several (maybe zero) reforms.Example Input 4
4 3
5 1 2 1
4 10
11 9 11 9
2 5
4 3
3 7
9 4 9
Output 2
4
0
3

题意

对一串数,你可以选择任意几个数平分它们,让它们都等于它们加和后的平均数。问最后最多有几个数可以达到给出的x值

思路

只需要排序后从最大值求出多余的值遍历可让多少数大于x。

代码

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,x,i;
        cin>>n>>x;
        int a[n+1];
       int count=0;
       long long sum=0;
       for(i=1;i<=n;i++)cin>>a[i];
       sort(a+1,a+n+1);
       for(i=n;i>=1;i--){
        if(sum+a[i]-x>=0){
            sum+=a[i]-x;
            count++;
        }
       }
       cout<<count<<endl;
    }
}

D - Circle of Monsters

You are playing another computer game, and now you have to slay nn

monsters. These monsters are standing in a circle, numbered clockwise from 11

to nn

. Initially, the ii

-th monster has aiai

health.You may shoot the monsters to kill them. Each shot requires exactly one bullet and decreases the health of the targeted monster by 11

(deals 11

damage to it). Furthermore, when the health of some monster ii

becomes 00

or less than 00

, it dies and explodes, dealing bibi

damage to the next monster (monster i+1i+1

, if i<ni<n

, or monster 11

, if i=ni=n

). If the next monster is already dead, then nothing happens. If the explosion kills the next monster, it explodes too, damaging the monster after it and possibly triggering another explosion, and so on.You have to calculate the minimum number of bullets you have to fire to kill all nn

monsters in the circle.InputThe first line contains one integer TT

(1≤T≤1500001≤T≤150000

) — the number of test cases.Then the test cases follow, each test case begins with a line containing one integer nn

(2≤n≤3000002≤n≤300000

) — the number of monsters. Then nn

lines follow, each containing two integers aiai

and bibi

(1≤ai,bi≤10121≤ai,bi≤1012

) — the parameters of the ii

-th monster in the circle.It is guaranteed that the total number of monsters in all test cases does not exceed 300000300000

.OutputFor each test case, print one integer — the minimum number of bullets you have to fire to kill all of the monsters.Example Input 1
3
7 15
2 14
5 3
Output 6

题意

有n个怪物排成一圈,每个怪物有ai的血量,当它血量为0可爆炸并减小下一个怪物bi的血量,一发子弹打掉一滴血,最少用几发子弹。

思路

就是找到一个合适的位置打怪物,利用爆炸使怪物掉血。
先算出每个怪物死后爆炸可以使下一个剩多少血量,依次存入数组s并求和

代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=300010;

int t, n;
ll minn, sum, k, a[N], b[N];

int main()
{
	scanf("%d",&t);
	while (t--)
	{
		scanf("%d",&n);
		sum = 0;
		for (int i = 0; i < n; i++)
		{
			scanf("%lld %lld",&a[i],&b[i]);
			if (i && a[i] > b[i - 1]) sum += a[i] - b[i - 1];
		}
		if (a[0] > b[n - 1]) sum += a[0] - b[n - 1], minn = b[n - 1];
		else minn = a[0];
		for (int i = 1; i < n; i++)
		{
			if (a[i] > b[i - 1]) k = b[i - 1];
			else k = a[i];
			minn = min(k,minn);
		}
		printf("%lld\n",minn+sum);
	}
	return 0;
}

E - Kind Anton

Once again, Boris needs the help of Anton in creating a task. This time Anton needs to solve the following problem:There are two arrays of integers aa

and bb

of length nn

. It turned out that array aa

contains only elements from the set {−1,0,1}{−1,0,1}

.Anton can perform the following sequence of operations any number of times: Choose any pair of indexes (i,j)(i,j)

such that 1≤i<j≤n1≤i<j≤n

. It is possible to choose the same pair (i,j)(i,j)

more than once. Add aiai

to ajaj

. In other words, jj

-th element of the array becomes equal to ai+ajai+aj

. For example, if you are given array [1,−1,0][1,−1,0]

, you can transform it only to [1,−1,−1][1,−1,−1]

, [1,0,0][1,0,0]

and [1,−1,1][1,−1,1]

by one operation.Anton wants to predict if it is possible to apply some number (zero or more) of these operations to the array aa

so that it becomes equal to array bb

. Can you help him?InputEach test contains multiple test cases. The first line contains the number of test cases tt

(1≤t≤100001≤t≤10000

). The description of the test cases follows.The first line of each test case contains a single integer nn

(1≤n≤1051≤n≤105

) — the length of arrays.The second line of each test case contains nn

integers a1,a2,…,ana1,a2,…,an

(−1≤ai≤1−1≤ai≤1

) — elements of array aa

. There can be duplicates among elements.The third line of each test case contains nn

integers b1,b2,…,bnb1,b2,…,bn

(−109≤bi≤109−109≤bi≤109

) — elements of array bb

. There can be duplicates among elements.It is guaranteed that the sum of nn

over all test cases doesn’t exceed 105105

.OutputFor each test case, output one line containing “YES” if it’s possible to make arrays aa

and bb

equal by performing the described operations, or “NO” if it’s impossible.You can print each letter in any case (upper or lower).Example Input 5
3
1 -1 0
1 1 -2
3
0 1 1
0 2 2
2
1 0
1 41
2
-1 0
-1 -41
5
0 1 -1 1 -1
1 1 -1 1 -1
Output YES
NO
YES
YES
NO

题意

给出一个数组a和数组b,a中只存在1,0,-1三种数字,b中是任意的数,能否使a通过(条件:a中任意下标的数只能加上它前面的数)操作变成b

思路

找到变化的数字如果增加判断之前有没有-1,如果减少判断之前有无1。

代码

#include<iostream>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,i,num1=0,num2=0,num3=0;
        cin>>n;
        int a[n],b[n];
        for(i=0;i<n;i++){
            cin>>a[i];
            if(a[i]==-1)num1++;
            if(a[i]==0)num2++;
            if(a[i]==1)num3++;
        }
        for(i=0;i<n;i++)cin>>b[i];
        int sim=1;
        for(i=n-1;i>=0;i--){
            if(a[i]==-1)num1--;
            if(a[i]==0)num2--;
            if(a[i]==1)num3--;
            if(a[i]>b[i]){
                if(num1>0)continue;
                else {sim=0;break;}
            }
            else if(a[i]<b[i]){
                if(num3>0)continue;
                else {sim=0; break;}
            }
        }
        if(sim==1)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

F - Eugene and an array

Eugene likes working with arrays. And today he needs your help in solving one challenging task.An array cc

is a subarray of an array bb

if cc

can be obtained from bb

by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.Let’s call a nonempty array good if for every nonempty subarray of this array, sum of the elements of this subarray is nonzero. For example, array [−1,2,−3][−1,2,−3]

is good, as all arrays [−1][−1]

, [−1,2][−1,2]

, [−1,2,−3][−1,2,−3]

, [2][2]

, [2,−3][2,−3]

, [−3][−3]

have nonzero sums of elements. However, array [−1,2,−1,−3][−1,2,−1,−3]

isn’t good, as his subarray [−1,2,−1][−1,2,−1]

has sum of elements equal to 00

.Help Eugene to calculate the number of nonempty good subarrays of a given array aa

.InputThe first line of the input contains a single integer nn

(1≤n≤2×1051≤n≤2×105

) — the length of array aa

.The second line of the input contains nn

integers a1,a2,…,ana1,a2,…,an

(−109≤ai≤109−109≤ai≤109

) — the elements of aa

. OutputOutput a single integer — the number of good subarrays of aa

.Examples Input 3
1 2 -3
Output 5
Input 3
41 -41 41
Output 3

题意

找出一个数组有几个子序列的和不为零的子序列

思路

求出前缀和,利用map除掉重复的情况。

代码

#include<iostream>
#include<map>
#include<cmath>
using namespace std;
int n,a[200005];
long long sum[200005]={0};
map<long long,int>mp;
int main()
{
   cin>>n;
   int i;
    for(i=1;i<=n;i++){
    cin>>a[i];
    sum[i]=sum[i-1]+(long long)a[i];
    }
    long long ans=0;
    int l=0,r;
    mp[0]=0;
    for(r=1;r<=n;r++)
    {
        if(mp.count(sum[r])==0)
        {
            ans+=r-l;
        }
        else
        {
            l=max(l,mp[sum[r]]+1);
            ans+=r-l;
        }
        mp[sum[r]]=r;
    }
    cout<<ans;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值