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;
}