Codeforces Round #767 (Div2) 题解

A. Download More RAM (CF1629A)

题目链接
Did you know you can download more RAM? There is a shop with n different pieces of software that increase your RAM. The i-th RAM increasing software takes ai GB of memory to run (temporarily, once the program is done running, you get the RAM back), and gives you an additional bi GB of RAM (permanently). Each software can only be used once. Your PC currently has k GB of RAM.
Note that you can’t use a RAM-increasing software if it takes more GB of RAM to use than what you currently have.
Since RAM is the most important thing in the world, you wonder, what is the maximum possible amount of RAM achievable?

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.
The first line of each test case contains the integers n and k (1≤n≤100, 1≤k≤1000). Then two lines follow, each containing n integers describing the arrays a and b (1≤ai,bi≤1000).

Output

For each test case, output a single line containing the largest amount of RAM you can achieve.

Example

input

4
3 10
20 30 10
9 100 10
5 1
1 1 5 1 1
1 1 1 1 1
5 1
2 2 2 2 2
100 100 100 100 100
5 8
128 64 32 16 8
128 64 32 16 8

output

29
6
1
256

Note

In the first test case, you only have enough RAM to run the third software initially, but that increases your RAM to 20 GB, which allows you to use the first software, increasing your RAM to 29 GB. The only software left needs 30 GB of RAM, so you have to stop here.
In the second test case, you can use the first, second, fourth and fifth software that need only 1 GB of RAM per software to run to increase your RAM to 5 GB, and then use the last remaining one to increase your RAM to 6 GB.
In the third test case, all the software need more than 1 GB of RAM to run, so the amount of RAM you have stays at 1 GB.

解题思路

一个简单的问题,可以使用贪心,将需要RAM最大的软件排在前面先进行操作,这样便可以使得每次到下个软件时电脑的RAM是最大的,因此贪心的策略是有效的。

AC代码

#include<bits/stdc++.h>
using namespace std;
int t,n,k; 
struct rj{
	int a,b;
}s[1005];
bool cmp(rj e1,rj e2)
{
	return e1.a<e2.a;
	if(e1.a==e2.a)
	  return e1.b>e2.b;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	  {
	  	scanf("%d%d",&n,&k);
	  	for(int i=1;i<=n;++i)
	  	  scanf("%d",&s[i].a);
	  	for(int i=1;i<=n;++i)
	  	  scanf("%d",&s[i].b);
	  	sort(s+1,s+1+n,cmp);
	  	for(int i=1;i<=n;++i)
	  	  {
	  	  	if(k>=s[i].a)
	  	  	  k+=s[i].b;
	  	  	else 
			  break;
	  	  }	  	
	  	printf("%d\n",k);
      }
}

B.GCD Arrays (CF1629B)

题目链接
Consider the array a composed of all the integers in the range [l,r]. For example, if l=3 and r=7, then a=[3,4,5,6,7].
Given l, r, and k, is it possible for gcd(a) to be greater than 1 after doing the following operation at most k times?
Choose 2 numbers from a.
Permanently remove one occurrence of each of them from the array.
Insert their product back into a.
gcd(b) denotes the greatest common divisor (GCD) of the integers in b.

Input

The first line of the input contains a single integer t (1≤t≤105) — the number of test cases. The description of test cases follows.
The input for each test case consists of a single line containing 3 non-negative integers l, r, and k (1≤l≤r≤109,0≤k≤r−l).

Output

For each test case, print “YES” if it is possible to have the GCD of the corresponding array greater than 1 by performing at most k operations, and “NO” otherwise (case insensitive).

Example

input

9
1 1 0
3 5 1
13 13 0
4 4 0
3 7 4
4 10 3
2 4 0
1 7 3
1 5 3

output

NO
NO
YES
YES
YES
YES
NO
NO
YES

Note

For the first test case, a=[1], so the answer is “NO”, since the only element in the array is 1.
For the second test case the array is a=[3,4,5] and we have 1 operation. After the first operation the array can change to: [3,20], [4,15] or [5,12] all of which having their greatest common divisor equal to 1 so the answer is “NO”.
For the third test case, a=[13], so the answer is “YES”, since the only element in the array is 13.
For the fourth test case, a=[4], so the answer is “YES”, since the only element in the array is 4.

解题思路

因为给出的是一组连续的数,所以合并过程中,要满足题目条件最大公因数大于一的最少次操作思路应该是将所有的数的公因数变为2,而一个数与另一个偶数相乘总为偶数,因此问题也便简化成统计数组内单数的数量。需要注意的是,并不能通过枚举来统计,这样会超时。另外边界都为1的情况也需要特判。

AC代码

#include<bits/stdc++.h>
using namespace std;
int n,l,r,cnt,need;
int main()
{	
	scanf("%d",&n);
	while(n--)
	  {
	  	need=0;
	  	scanf("%d%d%d",&l,&r,&cnt);
	    if((r-l+1)%2==0)
	      need=(r-l+1)/2;
	    else
	      {
	      	if(l%2==0)
	      	  need=(r-l+1)/2;
	      	else 
			  need=(r-l+1)/2+1;
	      }
		if(l==r&&l==1)
		  {
		  	printf("NO\n");
		  	continue;
		  }
	  	if(cnt<need&&l!=r)
	  	  printf("NO\n");
	  	else 
	  	  printf("YES\n");
	  } 
}

C. Maximum Array (CF1628A)

题目链接
Mihai has just learned about the MEX concept and since he liked it so much, he decided to use it right away.
Given an array a of n non-negative integers, Mihai wants to create a new array b that is formed in the following way:
While a is not empty:

  • Choose an integer k (1≤k≤|a|).
  • Append the MEX of the first k numbers of the array a to the end of array b and erase them from the array a, shifting the positions of the remaining numbers in a.
    But, since Mihai loves big arrays as much as the MEX concept, he wants the new array b to be the lexicographically maximum. So, Mihai asks you to tell him what the maximum array b that can be created by constructing the array optimally is.
    An array x is lexicographically greater than an array y if in the first position where x and y differ xi>yi or if |x|>|y| and y is a prefix of x (where |x| denotes the size of the array x).
    The MEX of a set of non-negative integers is the minimal non-negative integer such that it is not in the set. For example, MEX({1,2,3}) =0 and MEX({0,1,2,4,5}) =3.

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer n (1≤n≤2⋅105) — the number of elements in the array a.
The second line of each test case contains n non-negative integers a1,…,an (0≤ai≤n), where ai is the i-th integer from the array a.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output

For each test case print m — the length of the maximum array b Mihai can create, followed by m integers denoting the elements of the array b.

Example

input

6
5
1 0 2 0 3
8
2 2 3 4 0 1 2 0
1
1
5
0 1 2 3 4
4
0 1 1 0
10
0 0 2 1 1 1 0 0 1 1

output

1
4
2
5 1
1
0
1
5
2
2 2
4
3 2 2 0

Note

In the first test case, the lexicographically maximum array b is obtained by selecting k=5, resulting in the MEX of the whole array a. It is lexicographically maximum because an array starting with a smaller number than 4 is lexicographically smaller, and choosing a k<5 would result in an array starting with a number smaller than 4.
In the second test case, there are two ways to obtain the maximum array: first selecting k=6, then k=2, or first selecting k=7 and then k=1.

解题思路

根据题意,MEX是最小未出现自然数,拿 2 2 3 4 0 1 2 0 这个样例分析,我们显然可以得到,应该在1 2的边界分割以获得要求的最大值5,接着剩下的为答案贡献1。
我们可以将所有数字按1~n编号,接着列出这么一个表。

数字出现位置
08,5
16
27,2,1
33
44

我们取最大值5的时候容易发现,比5小的数的最前出现位置的最大值为6,也就是我们需要从6断开,并将表中所有小于等于 6 的出现位置拿掉,表示已被切割,这个时候我们的表中只剩下两项,分别是 0 对应 8 和 2 对应 7 。
我们可以用代码的形式将我们对表的操作进行模拟。

AC代码

#include<bits/stdc++.h>
using namespace std;
int t,maxn,n,index,maxindex;
int a[200005];
int main()
{   
	scanf("%d",&t);
	while(t--)
	  {
	  	index=0;
	  	scanf("%d",&n);
		vector<int>v[n+1];
        vector<int>ans;
	  	for(int i=0;i<n;++i)
	  	  scanf("%d",&a[i]);
	  	for(int i=n-1;i>=0;--i)
	  	  v[a[i]].push_back(i);
	  	while(index!=n)
	  	  {
	  	  	maxindex=index;
	  	  	for(int i=0;i<=n;++i)
	  	  	  {
	  	  	    while(v[i].size()>0&&v[i].back()<index)
	  	  	  	  v[i].pop_back();
	  	  	  	if(v[i].size()>0)
	  	  	  	  maxindex=max(maxindex,v[i].back());
	  	  	  	else
	  	  	  	  {
	  	  	  	  	ans.push_back(i);
	  	  	  	  	index=maxindex+1;
	  	  	  	  	break;
	  	  	  	  }
	  	  	  }
	  	  }
	  	printf("%d\n",ans.size());
	  	for(auto it: ans)
	  	  printf("%d ",it);
	  	printf("\n");
	  }
}

D.Peculiar Movie Preferences(CF1628B)

题目链接
Mihai plans to watch a movie. He only likes palindromic movies, so he wants to skip some (possibly zero) scenes to make the remaining parts of the movie palindromic.
You are given a list s of n non-empty strings of length at most 3, representing the scenes of Mihai’s movie.
A subsequence of s is called awesome if it is non-empty and the concatenation of the strings in the subsequence, in order, is a palindrome.
Can you help Mihai check if there is at least one awesome subsequence of s?
A palindrome is a string that reads the same backward as forward, for example strings “z”, “aaa”, “aba”, “abccba” are palindromes, but strings “codeforces”, “reality”, “ab” are not.
A sequence a is a non-empty subsequence of a non-empty sequence b if a can be obtained from b by deletion of several (possibly zero, but not all) elements.

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer n (1≤n≤105) — the number of scenes in the movie.
Then follows n lines, the i-th of which containing a single non-empty string si of length at most 3, consisting of lowercase Latin letters.
It is guaranteed that the sum of n over all test cases does not exceed 105.

Output

For each test case, print “YES” if there is an awesome subsequence of s, or “NO” otherwise (case insensitive).

Example

input

6
5
zx
ab
cc
zx
ba
2
ab
bad
4
co
def
orc
es
3
a
b
c
3
ab
cd
cba
2
ab
ab

output

YES
NO
NO
YES
YES
NO

Note

In the first test case, an awesome subsequence of s is [ab,cc,ba]

题解思路

这是一道与回文串有关的题目,但是非常简单,因为字符串长度很小,我们甚至不需要使用使用马拉车算法。只要知道策略,这道题目很容易解决。我们只需要满足能弄出一个回文串就够了,而且字符串的长度被控制在3以下。
也就是我们找出的最短回文串的长度在1~6的范围内。这是容易证明的,若回文串更长,显然它们之间,包含了更小的字符串,下面我们进行分类讨论。

  • 对于长度为1的字符串,显然它是回文串。
  • 对于长度为2与3的字符串,我们首先考虑它们自己是否为回文串。
  • 接着我们与已知的字符串进行倒序匹配,判断其是否能合成字符串。

这种操作也便是对a,aa,aba诸如此类的字符串先进行判断,显然它们能够满足题意。
接着对两段字符串的合成,对于输入的长度为2以及3的字符串,将其倒序与之前的串进行匹配,若有相等的,则满足题意。
但是,还有一种情况,那么便是长度为2,3字符串的匹配,这也很容易实现,我们将3截成2存入即可。

AC代码

#include<bits/stdc++.h>
#define all(x) (x).begin(),(x).end() 
using namespace std;
int t,n,flag;
bool ispalindrome(string s)
{
	int lens=s.length();
    for(int i=0;i<lens/2;++i)
	  {
	  	if(s[i]!=s[lens-i-1])
		  return false; 
	  }
	return true;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	  {
	  	flag=0;
	  	scanf("%d",&n);
	  	set<string>set2;
	    set<string>set3;
	    string s,rs;
	    while(n--)
	      {
	      	cin>>s;
	      	if(flag)
	      	  continue;
	        rs=s;
			reverse(all(rs));
			if(ispalindrome(s))
			  {
			  	flag=1;
			  	continue;
			  }
			if(s.length()==1)
			  {
			  	flag=1;
			  	continue;
			  }
			else if(s.length()==2)
			  {
			  	if(set2.find(rs)!=set2.end())
			  	  {
			  	  	flag=1;
			  	  	continue;
			  	  }
			  	if(set3.find(rs)!=set3.end())
			  	  {
			  	  	flag=1;
			  	  	continue;
			  	  }
			  	 set2.insert(s);
			  }	      
			else if(s.length()==3)
			  {
			  	if(set3.find(rs)!=set3.end())
			  	  {
			  	  	flag=1;
			  	  	continue;
			  	  }
			  	if(set2.find(rs.substr(0,2))!=set2.end())
			  	  {
			  	  	flag=1;
			  	  	continue;
			  	  }
			  	set3.insert(s);
			  	set3.insert(s.substr(0,2));
			  } 
		  }
		  if(flag)
		    printf("YES\n");
	      else 
	        printf("NO\n");
	  }
}

E.Grid Xor (CF1628C)

题目链接
Note: The XOR-sum of set {s1,s2,…,sm} is defined as s1⊕s2⊕…⊕sm, where ⊕ denotes the bitwise XOR operation.
After almost winning IOI, Victor bought himself an n×n grid containing integers in each cell. n is an even integer. The integer in the cell in the i-th row and j-th column is ai,j.
Sadly, Mihai stole the grid from Victor and told him he would return it with only one condition: Victor has to tell Mihai the XOR-sum of all the integers in the whole grid.
Victor doesn’t remember all the elements of the grid, but he remembers some information about it: For each cell, Victor remembers the XOR-sum of all its neighboring cells.
Two cells are considered neighbors if they share an edge — in other words, for some integers 1≤i,j,k,l≤n, the cell in the i-th row and j-th column is a neighbor of the cell in the k-th row and l-th column if |i−k|=1 and j=l, or if i=k and |j−l|=1.
To get his grid back, Victor is asking you for your help. Can you use the information Victor remembers to find the XOR-sum of the whole grid?
It can be proven that the answer is unique.

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single even integer n (2≤n≤1000) — the size of the grid.
Then follows n lines, each containing n integers. The j-th integer in the i-th of these lines represents the XOR-sum of the integers in all the neighbors of the cell in the i-th row and j-th column.
It is guaranteed that the sum of n over all test cases doesn’t exceed 1000 and in the original grid 0≤ai,j≤230−1.

Output

For each test case, output a single integer — the XOR-sum of the whole grid.

Example

input

3
2
1 5
5 1
4
1 14 8 9
3 1 5 9
4 13 11 1
1 15 4 11
4
2 4 1 6
3 7 3 10
15 9 4 2
12 7 15 1

output

4
9
5

Note

For the first test case, one possibility for Victor’s original grid is:
1 3
2 4
For the second test case, one possibility for Victor’s original grid is:
3 8 8 5
9 5 5 1
5 5 9 9
8 4 2 9
For the third test case, one possibility for Victor’s original grid is:
4 3 2 1
1 2 3 4
5 6 7 8
8 9 9 1

解题思路

对于每个方块,我们只需要判断它的相邻方块(上下左右)是否已经计算在内,若有则跳过,若无则将其异或进入答案中,答案的正确性证明可以画图实现,这里不证。

AC代码

#include<bits/stdc++.h>
using namespace std;
int t,x,n;
long long ans;
int main()
{
	scanf("%d",&t);
	while(t--)
	  {
	  	ans=0;
	  	scanf("%d",&n);
	  	int a[n+5][n+5];
		memset(a,0,sizeof(a));
	  	for(int i=1;i<=n;i++)
	  	  for(int j=1;j<=n;j++)
	  	    {
	  	    	scanf("%d",&x);
	  	    	if(!a[i][j-1]&&!a[i][j+1]&&!a[i-1][j]&&!a[i+1][j])
	  	    	  {
	  	    	  	ans^=x;
	  	    	  	a[i][j-1]++;
	  	    	    a[i][j+1]++;
	  	    	    a[i-1][j]++;
	  	    	    a[i+1][j]++;
	  	    	  }
	  	    }
	  	printf("%lld\n",ans);
	  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值