Codeforces Round #776 (Div. 3)题解A~E

799 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

codeforces-logo-with-telegram.png

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

序言

此为cf2022年3月8日的Codeforces Round #776 (Div. 3)场A~E题题解。

Problem - A - Codeforces

题目详情

The string s is given, the string length is odd number. The string consists of lowercase letters of the Latin alphabet.

As long as the string length is greater than 1, the following operation can be performed on it: select any two adjacent letters in the string s and delete them from the string. For example, from the string "lemma" in one operation, you can get any of the four strings: "mma", "lma", "lea" or "lem" In particular, in one operation, the length of the string reduces by 2.

Formally, let the string ss have the form s=s1s2…sn (n>1). During one operation, you choose an arbitrary index ii (1≤i<n) and replace s=s1s2…si−1si+2…sn.

For the given string ss and the letter cc, determine whether it is possible to make such a sequence of operations that in the end the equality s=cwill be true? In other words, is there such a sequence of operations that the process will end with a string of length 11, which consists of the letter c?

Input

The first line of input data contains an integer tt (1≤t≤10^3) — the number of input test cases.

The descriptions of the tt cases follow. Each test case is represented by two lines:

  • string s, which has an odd length from 11 to 49 inclusive and consists of lowercase letters of the Latin alphabet;
  • is a string containing one letter c, where cc is a lowercase letter of the Latin alphabet.

Output

For each test case in a separate line output:

  • YES, if the string s can be converted so that s=c is true;
  • NO otherwise.

You can output YES and NO in any case (for example, the strings yEs, yes, Yes and YES will be recognized as a positive response).

Example

input

5
abcde
c
abcde
b
x
y
aaaaaaaaaaaaaaa
a
contest
t

output

YES
NO
NO
YES
YES

题目描述

题目会给我们一个长度为奇数的字符串s,和一个单个字符c,我们每次可以删除s中的任意位置的相邻两个字符,问:我们有没有办法可以把字符串删除到只剩单字符c。

问题解析

既然只能删偶数的字母,那就直接遍历s,只要发现字符c,且下标是偶数(下标从0开始,如果你下标是偶数,就说明前面的字符个数也是偶数),那就输出yes。如果一直找不到就输出no。 因为字符串s长度为奇数,如果我们字符c的所在下标为偶数,说明它前面的字符数量为偶数,后面的字符数量也为偶数,是可以被两个两个删掉的。

AC代码

#include<iostream>
using namespace std;
#include<string>
 
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		string str;
		char c;
		cin >> str >> c;
		int n = str.size();
		bool flag = true;
		for (int i = 0; i < n; i++)
		{
			if (str[i] == c && i % 2 == 0)
			{
				cout << "YES" << endl;
				flag = false;
				break;
			}
		}
		if (flag)cout << "NO" << endl;
	}
	return 0;
}

Problem - B - Codeforces

题目详情

Not so long ago, Vlad came up with an interesting function:

  • fa(x)=⌊x/a⌋+x mod a, where ⌊x/a⌋ is x/a, rounded down, x mod a — the remainder of the integer division of x by a.

For example, with a=3 and x=11, the value f3(11)=⌊11/3⌋+11mod3=3+2=5.

The number a is fixed and known to Vlad. Help Vlad find the maximum value of fa(x)fa(x) if xx can take any integer value from ll to r inclusive (l≤x≤r).

Input

The first line of input data contains an integer tt (1≤t≤1041≤t≤104) — the number of input test cases.

This is followed by t lines, each of which contains three integers li, ri and ai (1≤li≤ri≤10^9,1≤ai≤10^9) — the left and right boundaries of the segment and the fixed value of a.

Output

For each test case, output one number on a separate line — the maximum value of the function on a given segment for a given a.

Example

input

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

output

2
4
5
999999999
5

题目描述

给你一个区间l~r和一个数a,让你从区间里找一个数x,使得x/a+x%a的值最大。

问题解析

暴力思路就是直接遍历区间l~r,枚举所有可能的x,然后计算x/a+x%a并维护最大值。但这里区间范围到了10^9,会超时。 但实际上这是一道数学题,我们分情况讨论:

  1. 区间里的数都小于a:x/a就只能是0了,那么我们要求的最大值只能从x%a里找,因为x都是小于a的,x越大,x%a就越大,所以当区间里的数都小于a时,我们直接输出右端点。

  2. 右区间大于a:x/a和x%a都有值,但这并不妨碍我们重复之前的操作,只是在x%a的情况下加上了x/a的值,也就是说,x%a部分的值我们仍然是从0~a-1的部分中去最大的那个a-1,至于前面的x/a,就看区间最大的值有几个a,我们计算r/a的值,记作ans,x的值就该是ans* a-1,这样函数的最大值就是(ans-1)+a-1了。

AC代码

#include<iostream>
using namespace std;
 
typedef long long ll;
typedef pair<int, int>PII; 
 
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		ll l, r, a;
		cin >> l >> r >> a;
		if (r < a)
		{
			cout << r << endl;
		}
		else if (r >= a)
		{
			ll ans = (r + 1) / a;
			ll x = (ans) * a - 1;
			if (l > x)
			{
				x = r;
			}
			cout << x / a + x % a << endl;
		}
		
	}
	return 0;
}

Problem - C - Codeforces

题目详情

On the number line there are mm points, ii-th of which has integer coordinate xi and integer weight wi. The coordinates of all points are different, and the points are numbered from 1 to m.

A sequence of nn segments [l1,r1],[l2,r2],…,[ln,rn] is called system of nested segments if for each pair i,j (1≤i<j≤n) the condition li<lj<rj<ri is satisfied. In other words, the second segment is strictly inside the first one, the third segment is strictly inside the second one, and so on.

For a given number nn, find a system of nested segments such that:

  • both ends of each segment are one of mm given points;
  • the sum of the weights 2⋅n2⋅n of the points used as ends of the segments is minimal.

For example, let m=8m=8. The given points are marked in the picture, their weights are marked in red, their coordinates are marked in blue. Make a system of three nested segments:

  • weight of the first segment: 1+1=2
  • weight of the second segment: 10+(−1)=9
  • weight of the third segment: 3+(−2)=1
  • sum of the weights of all the segments in the system: 2+9+1=12

imgSystem of three nested segments

Input

The first line of input data contains an integer t (1≤t≤10^4) —the number of input test cases.

An empty line is written before each test case.

The first line of each test case contains two positive integers nn (1≤n≤10^5) and mm (2⋅n≤m≤2⋅10^5).

The next mm lines contain pairs of integers xixi (−10^9≤xi≤10^9) and wiwi (−10^4≤wi≤10^4) — coordinate and weight of point number ii (1≤i≤m) respectively. All xi are different.

It is guaranteed that the sum of mm values over all test cases does not exceed 2⋅10^5.

Output

For each test case, output n+1 lines: in the first of them, output the weight of the composed system, and in the next nn lines output exactly two numbers — the indices of the points which are the endpoints of the ii-th segment (1≤i≤n1≤i≤n). The order in which you output the endpoints of a segment is not important — you can output the index of the left endpoint first and then the number of the right endpoint, or the other way around.

If there are several ways to make a system of nested segments with minimal weight, output any of them.

Example

input

3
​
3 8
0 10
-2 1
4 10
11 20
7 -1
9 1
2 3
5 -2
​
3 6
-1 2
1 3
3 -1
2 4
4 0
8 2
​
2 5
5 -1
3 -2
1 0
-2 0
-5 -3

output

12
2 6
5 1
7 8
​
10
1 6
5 2
3 4
​
-6
5 1
4 2

题目描述

这题是说,给你一个数字n和m个点,每个点有一个坐标和权重,你现在要把这些点按他们的坐标排序好,然后连成n个线段,线段成涟漪状(大的包住小的)每个线段的权是两个端点的权重之和,问你这n个线段的权和最小是多少,并且从外到内输出这些线段的端点的下标(不是坐标,是输入时的下标,从1开始计数)。

问题解析

既然他要的是权和最小,那我们大可以直接根据每个点的权值大小进行排序,就取权值最小的2n个点,然后根据当时输入的顺序依照题目描述连接成n条线段并输出。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

typedef long long ll;
typedef pair<ll, ll>PII;

bool cmp(vector<ll> a, vector<ll> b)
{
	return a[2] < b[2];
}

bool cmp2(vector<ll> a, vector<ll> b)
{
	return a[1] < b[1];
}

int main()
{
	int m;
	cin >> m;
	while (m--)
	{
		int n, len;
		cin >> n >> len;
		vector<vector<ll>>v(len, vector<ll>(3));
		for (int i = 0; i < len; i++)
		{
			cin >> v[i][1] >> v[i][2];
			v[i][0] = i;
		}
		sort(v.begin(), v.end(),cmp);
		v.erase(v.begin() + 2 * n, v.end());
		sort(v.begin(), v.end(), cmp2);
		ll sum = 0;
		for (auto i : v)sum += i[2];
		cout << sum << endl;
		int l = 0, r = v.size();
		while (l < r-1)
		{
			cout << v[l][0]+1 << " " << v[r-1][0]+1 << endl;
			l++, r--;
		}
	}
	return 0;
}

Problem - D - Codeforces

题目详情

Petya got an array aa of numbers from 1 to nn, where a[i]=i.

He performed n operations sequentially. In the end, he received a new state of the a array.

At the ii-th operation, Petya chose the first i elements of the array and cyclically shifted them to the right an arbitrary number of times (elements with indexes i+1 and more remain in their places). One cyclic shift to the right is such a transformation that the array a=[a1,a2,…,an]becomes equal to the array a=[ai,a1,a2,…,ai−2,ai−1,ai+1,ai+2,…,an].

For example, if a=[5,4,2,1,3] and i=3 (that is, this is the third operation), then as a result of this operation, he could get any of these three arrays:

  • a=[5,4,2,1,3] (makes 00 cyclic shifts, or any number that is divisible by 3);
  • a=[2,5,4,1,3] (makes 1 cyclic shift, or any number that has a remainder of 1 when divided by 3);
  • a=[4,2,5,1,3] (makes 2 cyclic shifts, or any number that has a remainder of 2 when divided by 3).

Let's look at an example. Let n=6, i.e. initially a=[1,2,3,4,5,6] A possible scenario is described below.

  • i=1: no matter how many cyclic shifts Petya makes, the array aa does not change.
  • i=2: let's say Petya decided to make a 1 cyclic shift, then the array will look like a=[2,1,3,4,5,6].
  • i=3: let's say Petya decided to make 1 cyclic shift, then the array will look like a=[3,2,1,4,5,6].
  • i=4: let's say Petya decided to make 2 cyclic shifts, the original array will look like a=[1,4,3,2,5,6].
  • i=5: let's say Petya decided to make 0 cyclic shifts, then the array won't change.
  • i=6: let's say Petya decided to make 4 cyclic shifts, the array will look like a=[3,2,5,6,1,4].

You are given a final array state aa after all nn operations. Determine if there is a way to perform the operation that produces this result. In this case, if an answer exists, print the numbers of cyclical shifts that occurred during each of the nn operations.

Input

The first line of the input contains an integer tt (1≤t≤500) — the number of test cases in the test.

The descriptions of the test cases follow.

The first line of the description of each test case contains one integer nn (2≤n≤2⋅10^3) — the length of the array aa.

The next line contains the final state of the array aa: nn integers a1,a2,…,an (1≤ai≤n) are written. All aiai are distinct.

It is guaranteed that the sum of nn values over all test cases does not exceed 2⋅10^3.

Output

For each test case, print the answer on a separate line.

Print -1 if the given final value a cannot be obtained by performing an arbitrary number of cyclic shifts on each operation. Otherwise, print n non-negative integers d1,d2,…,dn (di≥0), where didi means that during the ii-th operation the first i elements of the array were cyclic shifted to the right didi times.

If there are several possible answers, print the one where the total number of shifts is minimal (that is, the sum of di values is the smallest). If there are several such answers, print any of them.

Example

input

3
6
3 2 5 6 1 4
3
3 1 2
8
5 8 1 3 2 6 4 7

output

0 1 1 2 0 4 
0 0 1 
0 1 2 0 2 5 6 2 

题目描述

给你一个长度为n的数组,这个数组的元素组成是 1, 2 …… n-1, n ;而且原本顺序也该是这样子的,即从1到n的单调递增函数,但经历了一些操作后变成了它给的这样,问当初的数组是经过了什么样的变化变成了如今的样子,让你输出变化操作次数的数组。

变化的方法是,从i=1开始到i=n,每次取数组的前i个元素进行旋转,比如i是3,数组是1 2 3 4 5,那就是取前三个元素1 2 3进行旋转,旋转的次数你来决定,如果旋转一次,那就是变成3 1 2,这样原来数组就是3 1 2 4 5了,由此类推。而你要输出的变化的数组就是,当选中前i个数后,旋转的次数。

问题解析

既然它是原本有序的数组经过一系列变化变成了如今无序的样子,那我们反着来,只要反着操作,我们就可以用原来的变化顺序把现在的数组变回之前有序的情况,怎么反着来,原来变化的时候,每次选前i个数,i的取值是从1~ n递增,那我们只要从n~1递减即可,而且之前旋转,都是向右旋转(1 2 3变成了3 1 2),我们就向左旋转 (1 2 3变成2 3 1),然后就是把每个数移动到对应的位置上即可,如果是三,就把它放到下标为2的地方(下标从0开始),如果是5就放到下标为4的位置。那么我们该怎么做呢。

首先我们前面说了,我们每次取前i个数进行旋转,而且i的取值是从大到小的,比如数组2 3 5 4 1,我们第一次是选前5个数进行旋转,第二次是选前4个数进行旋转,你应该发现了,如果我们想复原第五个位置上的数,只有一个机会,那就是在旋转前5个数的时候,把5这个数移动到第五个位置上,毕竟之和就算进行旋转,也不会再影响到第五个位置上的数了。此时做法就很明显了,我们每次遍历前i个数,找到对应的那个数,比如2 3 5 4 1这个数组,5在下标为2的位置上,那么我们就是要旋转2+1=3次,才能把数字5放在第五个位置上,此时数组为4 1 2 3 5,这样就算完成了第一步,变幻数组(我们最后要输出的那个)第5个位置上的值就是我们旋转的次数:2+1=3。然后我们如法炮制继续找到其他的数即可。要注意的是,如果要找的数已经在它应该在的位置上了,那我们不进行任何操作,变换数组对应位置上的值也就是0.

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
 
typedef long long ll;
typedef pair<ll, ll>PII;
 
 
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		vector<int>v(n), res(n);
		for (int i = 0; i < n; i++)cin >> v[i];
		for (int i = n - 1; i >= 0; i--)
		{
			int ans = -1;
			for (int j = 0; j <= i; j++)
			{
				if (v[j] == i+1)
				{
					ans = j;
					break;
				}
			}
			if (ans!=-1&&v[ans] == ans + 1)continue;
			res[i] = ans + 1;
			vector<int>v1;
			v1.assign(v.begin(), v.begin() + (ans + 1));
			int l = 0;
			for (int j = ans + 1; j <= i; j++)
				v[l++] = v[j];
			for (auto i : v1)
			{
				v[l++] = i;
			}
		}
		for (int i = 0; i < n; i++)cout << res[i] << " ";
		cout << endl;
	}
 
 
	return 0;
}

Problem - E - Codeforces

题目详情

Now Dmitry has a session, and he has to pass n exams. The session starts on day 11 and lasts d days. The iith exam will take place on the day of ai (1≤ai≤d), all ai — are different.

imgSample, where n=3, d=12, a=[3,5,9]. Orange — exam days. Before the first exam Dmitry will rest 22 days, before the second he will rest 11 day and before the third he will rest 33 days.

For the session schedule, Dmitry considers a special value μμ — the smallest of the rest times before the exam for all exams. For example, for the image above, μ=1μ=1. In other words, for the schedule, he counts exactly n numbers — how many days he rests between the exam i−1 and ii (for i=0 between the start of the session and the exam ii). Then it finds μ — the minimum among these n numbers.

Dmitry believes that he can improve the schedule of the session. He may ask to change the date of one exam (change one arbitrary value of ai). Help him change the date so that all ai remain different, and the value of μμ is as large as possible.

For example, for the schedule above, it is most advantageous for Dmitry to move the second exam to the very end of the session. The new schedule will take the form:

imgNow the rest periods before exams are equal to 2,2,5. So, μ=2.

Dmitry can leave the proposed schedule unchanged (if there is no way to move one exam so that it will lead to an improvement in the situation).

Input

The first line of input data contains an integer t (1≤t≤10^4) — the number of input test cases. The descriptions of test cases follow.

An empty line is written in the test before each case.

The first line of each test case contains two integers n and d (2≤n≤2⋅10^5,1≤d≤10^9) — the number of exams and the length of the session, respectively.

The second line of each test case contains n integers ai (1≤ai≤d,ai<ai+1), where the ii-th number means the date of the ii-th exam.

It is guaranteed that the sum of nn for all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, output the maximum possible value of μ if Dmitry can move any one exam to an arbitrary day. All values of ai should remain distinct.

Example

input

9
​
3 12
3 5 9
​
2 5
1 5
​
2 100
1 2
​
5 15
3 6 9 12 15
​
3 1000000000
1 400000000 500000000
​
2 10
3 4
​
2 2
1 2
​
4 15
6 11 12 13
​
2 20
17 20

output

2
1
1
2
99999999
3
0
1
9

题目描述

你现在有n场考试要在d天内考完,考试的时间已经确定了,你每场考试前都想要有足够的时间,但有些考试时间挨得太近了,但你现在可以随意把一场考试移到其它时间去,问你怎么移动可以使得你每场考试间隔的最小时间尽可能多。

问题解析

通过描述我们不难看出,该题的思想就是贪心。

首先肯定就是要找到距离最小的那个位置,那个就是我们要修改的考试时间,我们把那个点拿出来,然后重新计算两两点之间的距离,此时,最小距离就有三种可能:

1、重新计算距离后中的最小距离 2、把移出来的那场考试的点移动到最大距离中间后得到的距离 3、把那场考试移动到最后一天

这三种情况得到的距离我们设为min_len,(max_len-1)/2 , d-a[i]-1。因为第一种情况是客观存在的,我们无法对他进行修改,我们只能从第2和第3种情况中取得到距离最大的,然后再和min_len比较,输出较小的那个。

有一点要注意的是,我们一开始求得的最小距离可能和两场考试有关,举个例子,d=10,考试数是:5 7 8 第三场考试前的休息天数是1,那么第二场考完试后的休息天数也是这个1,造成了这个休息天数只有1天的不光只和第三场考试有关,第二长考试也是和这个最短距离挨着的,所以我们还应该假设一下,如果把第二场考试移动到其它地方,可以获得的最小距离是多少。方法和上面一样。最后我们可以从这两个最小距离中选最大的一种结果,这里可以选择是因为我们可以选择移动第二次考试或第三次考试,而不是像求最小距离时那样不能移动考试场数。既然能选我们就要选最大的。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
 
typedef long long ll;
typedef pair<int, int>PII;
 
int get_min(vector<int>space,int m)
{
    int n = space.size(), max_len = 0, min_len = 1e9;
    for (int i = 1; i < n; i++)
    {
        max_len = max(space[i] - space[i - 1] - 1, max_len);
        min_len = min(space[i] - space[i - 1] - 1, min_len);
    }
    return min(min_len, max((max_len - 1) / 2, m - 1 - space[n - 1]));
}
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        int n, m, min_len = 1e9, sub = -1;
        cin >> n >> m;
        vector<int>v(n + 1), space;
        for (int i = 1; i <= n; i++)
        {
            cin >> v[i];
            int len = v[i] - v[i - 1] - 1;
            if (min_len > len)
            {
                min_len = len;
                sub = i;
            }
        }
        for (int i = 0; i <= n; i++)
        {
            if (i != sub)
                space.push_back(v[i]);
        }
        int res = get_min(space, m);
        if (sub > 1)
        {
            space[sub-1] = v[sub];
        }
        res = max(res, get_min(space, m));
        cout << res << endl;
    }
 
    return 0;
}