Codeforces Round #648 (Div. 2) 【A-F思路及题解】

A. Matrix Game

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

Ashish and Vivek play a game on a matrix consisting of n rows and m columns, where they take turns claiming cells. Unclaimed cells are represented by 0, while claimed cells are represented by 1. The initial state of the matrix is given. There can be some claimed cells in the initial state.

In each turn, a player must claim a cell. A cell may be claimed if it is unclaimed and does not share a row or column with any other already claimed cells. When a player is unable to make a move, he loses and the game ends.

If Ashish and Vivek take turns to move and Ashish goes first, determine the winner of the game if both of them are playing optimally.

Optimal play between two players means that both players choose the best possible strategy to achieve the best possible outcome for themselves.

Input
The first line consists of a single integer t (1≤t≤50) — the number of test cases. The description of the test cases follows.

The first line of each test case consists of two space-separated integers n, m (1≤n,m≤50) — the number of rows and columns in the matrix.

The following n lines consist of m integers each, the j-th integer on the i-th line denoting ai,j (ai,j∈{0,1}).

Output
For each test case if Ashish wins the game print “Ashish” otherwise print “Vivek” (without quotes).

Example
input
4
2 2
0 0
0 0
2 2
0 0
0 1
2 3
1 0 1
1 1 0
3 3
1 0 0
0 0 0
1 0 0
output
Vivek
Ashish
Vivek
Ashish

Note
For the first case: One possible scenario could be: Ashish claims cell (1,1), Vivek then claims cell (2,2). Ashish can neither claim cell (1,2), nor cell (2,1) as cells (1,1) and (2,2) are already claimed. Thus Ashish loses. It can be shown that no matter what Ashish plays in this case, Vivek will win.

For the second case: Ashish claims cell (1,1), the only cell that can be claimed in the first move. After that Vivek has no moves left.

For the third case: Ashish cannot make a move, so Vivek wins.

For the fourth case: If Ashish claims cell (2,3), Vivek will have no moves left.

题意:给一个n*m的01矩阵,两人轮流将0转化为1,若点pos可以被转化,那么要求x行和y列没有1。谁不能转谁输。

思路:计算所有满足的点的数量,根据奇偶性判断。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		int n,m;
		scanf("%d %d",&n,&m);
		vector<bool> col(m+1,0), row(n+1,0);
		for(int i=1; i<=n; ++i)	{
			for(int j=1; j<=m; ++j)	{
				int a;
				scanf("%d",&a);
				if(a) {
					col[j] = 1;
					row[i] = 1;
				}
			}
		}
		
		int ans=0;
		for(int i=1; i<=n; ++i)	{
			for(int j=1; j<=m; ++j)	{
				if(col[j]==0 && row[i]==0) {
					ans++;
					col[j] = 1;
					break;
				}
			}
		}
		
		if(ans%2 == 1)	printf("Ashish\n");
		else  printf("Vivek\n");
	}
	return 0;
}

B. Trouble Sort

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Ashish has n elements arranged in a line.

These elements are represented by two integers ai — the value of the element and bi — the type of the element (there are only two possible types: 0 and 1). He wants to sort the elements in non-decreasing values of ai.

He can perform the following operation any number of times:

Select any two elements i and j such that bi≠bj and swap them. That is, he can only swap two elements of different types in one move.
Tell him if he can sort the elements in non-decreasing values of ai after performing any number of operations.

Input
The first line contains one integer t (1≤t≤100) — the number of test cases. The description of the test cases follows.

The first line of each test case contains one integer n (1≤n≤500) — the size of the arrays.

The second line contains n integers ai (1≤ai≤105) — the value of the i-th element.

The third line containts n integers bi (bi∈{0,1}) — the type of the i-th element.

Output
For each test case, print “Yes” or “No” (without quotes) depending on whether it is possible to sort elements in non-decreasing order of their value.

You may print each letter in any case (upper or lower).

Example
input
5
4
10 20 20 30
0 1 0 1
3
3 1 2
0 1 1
4
2 2 4 8
1 1 1 1
3
5 15 4
0 0 0
4
20 10 100 50
1 0 0 1
output
Yes
Yes
Yes
No
Yes

Note
For the first case: The elements are already in sorted order.

For the second case: Ashish may first swap elements at positions 1 and 2, then swap elements at positions 2 and 3.

For the third case: The elements are already in sorted order.

For the fourth case: No swap operations may be performed as there is no pair of elements i and j such that bi≠bj. The elements cannot be sorted.

For the fifth case: Ashish may swap elements at positions 3 and 4, then elements at positions 1 and 2.

题意:给长度为为n的数组,每个数拥有属性(0或1),问是否能够将数组通过swap操作变为非递减数组,交换的两个数的属性必须不相同。

思路:可以思考一下,如果要排序属性为0的,只要有一个1存在,就可以用这个1作为媒介交换两个0,反之亦然,因此如果属性1和属性0的数都有,必定可以排序。如果0或1没有,那么直接判断原数组是否是非递减序列。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

struct node {
	LL a;
	int b;
}T[505];
int t,n,o,z;
 
void solve()
{
	for(int ct=1; ct<=t; ++ct) {
		cin>>n;
		o=0 , z=0;
		bool vis = true;
		for(int i=1 ; i<=n ; ++i) {
			scanf("%lld", &T[i].a);
			if(T[i].a-T[i-1].a < 0)  vis=false;
		}
		bool flag=true;
		int i=1;
		while(i<=n)	{
			scanf("%d",&T[i].b);
			if(T[i].b)  ++o;
			else  ++z;
			++i;
		}
		if((!o||!z) && !vis)  flag=false;
		if(flag)  printf("Yes\n");
		else  printf("No\n");
	}
}
 
int main()
{
	cin>>t;
	solve();
	return 0;
}

C. Rotation Matching

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
After the mysterious disappearance of Ashish, his two favourite disciples Ishika and Hriday, were each left with one half of a secret message. These messages can each be represented by a permutation of size n. Let’s call them a and b.

Note that a permutation of n elements is a sequence of numbers a1,a2,…,an, in which every number from 1 to n appears exactly once.

The message can be decoded by an arrangement of sequence a and b, such that the number of matching pairs of elements between them is maximum. A pair of elements ai and bj is said to match if:

i=j, that is, they are at the same index.
ai=bj
His two disciples are allowed to perform the following operation any number of times:

choose a number k and cyclically shift one of the permutations to the left or right k times.
A single cyclic shift to the left on any permutation c is an operation that sets c1:=c2,c2:=c3,…,cn:=c1 simultaneously. Likewise, a single cyclic shift to the right on any permutation c is an operation that sets c1:=cn,c2:=c1,…,cn:=cn−1 simultaneously.

Help Ishika and Hriday find the maximum number of pairs of elements that match after performing the operation any (possibly zero) number of times.

Input
The first line of the input contains a single integer n (1≤n≤2⋅105) — the size of the arrays.

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

The third line contains n integers b1, b2, …, bn (1≤bi≤n) — the elements of the second permutation.

Output
Print the maximum number of matching pairs of elements after performing the above operations some (possibly zero) times.

Examples
input
5
1 2 3 4 5
2 3 4 5 1
output
5
input
5
5 4 3 2 1
1 2 3 4 5
output
1
input
4
1 3 2 4
4 2 3 1
output
2

Note
For the first case: b can be shifted to the right by k=1. The resulting permutations will be {1,2,3,4,5} and {1,2,3,4,5}.

For the second case: The operation is not required. For all possible rotations of a and b, the number of matching pairs won’t exceed 1.

For the third case: b can be shifted to the left by k=1. The resulting permutations will be {1,3,2,4} and {2,3,1,4}. Positions 2 and 4 have matching pairs of elements. For all possible rotations of a and b, the number of matching pairs won’t exceed 2.

题意:给定两个排列,问能否通过左移右移操作将a序列和b序列相同数在同一位置的数量最多。左移右移操作定义为:对于序列c:左移操作为将所有数循环地向左移动一个位置,即变为:c1:=c2,c2:=c3,…,cn:=c1。右移类似。

思路:因为是排列,所以每个数出现且只出现一次,那么对于b排列中的任意一个数x,记录下x在a排列中的位置,即是要将b中的x与a对齐所需要的操作次数。记录下每一个操作次数所能够对齐的数量,取max即答案。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 2e5+10;
 
int n,a[maxn],b[maxn];
int num[maxn],pos[maxn];
 
void solve()
{
	for(int i=1; i<=n; ++i) {
		scanf("%d", a+i);
		pos[a[i]]=i ;
	}
	
	for(int i=1; i<=n; ++i) {
		scanf("%d",b+i);
		int res = i-pos[b[i]];
		if(res<0)  res+=n;
		num[res]++;
	}
	
	int ans=1,i=0;
	while(i<n)  {ans = max(ans,num[i++]);}
	printf("%d\n",ans);
}
 
int main()
{
	scanf("%d",&n);
	solve();
	return 0;
}

D. Solve The Maze

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vivek has encountered a problem. He has a maze that can be represented as an n×m grid. Each of the grid cells may represent the following:

Empty — ‘.’
Wall — ‘#’
Good person — ‘G’
Bad person — ‘B’
The only escape from the maze is at cell (n,m).

A person can move to a cell only if it shares a side with their current cell and does not contain a wall. Vivek wants to block some of the empty cells by replacing them with walls in such a way, that all the good people are able to escape, while none of the bad people are able to. A cell that initially contains ‘G’ or ‘B’ cannot be blocked and can be travelled through.

Help him determine if there exists a way to replace some (zero or more) empty cells with walls to satisfy the above conditions.

It is guaranteed that the cell (n,m) is empty. Vivek can also block this cell.

Input
The first line contains one integer t (1≤t≤100) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers n, m (1≤n,m≤50) — the number of rows and columns in the maze.

Each of the next n lines contain m characters. They describe the layout of the maze. If a character on a line equals ‘.’, the corresponding cell is empty. If it equals ‘#’, the cell has a wall. ‘G’ corresponds to a good person and ‘B’ corresponds to a bad person.

Output
For each test case, print “Yes” if there exists a way to replace some empty cells with walls to satisfy the given conditions. Otherwise print “No”

You may print every letter in any case (upper or lower).

Example
input
6
1 1
.
1 2
G.
2 2
#B
G.
2 3
G.#
B#.
3 3
#B.
#…
GG.
2 2
#B
B.
output
Yes
Yes
No
No
Yes
Yes

Note
For the first and second test cases, all conditions are already satisfied.

For the third test case, there is only one empty cell (2,2), and if it is replaced with a wall then the good person at (1,2) will not be able to escape.

For the fourth test case, the good person at (1,1) cannot escape.

For the fifth test case, Vivek can block the cells (2,3) and (2,2).

For the last test case, Vivek can block the destination cell (2,2).

题意:给一个n*m的迷宫,里面有好人坏人和墙壁,问能不能通过增加墙壁使的所有好人能够到达出口而所有坏人不能。出口在点(nm)。

思路:暴力找出所有坏人的位置,在他们四周放上墙壁,在过程中判断放墙壁的位置是否有好人,有的话则不行。若堵住了所有坏人且没有好人在坏人相邻的格子情况下,从出口BFS标记所有能到达出口的点,再暴力循环一遍找所有好人的位置,只要所有好人的位置都被标记,那么好人就可以到达出口,反之不行。

#include <bits/stdc++.h>
#define pb push_back
#define LL long long
#define PII pair<int, int>
#define Pque priority_queue 
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;

 
int n, m, t;
char a[55][55];
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
bool vis[55][55];
 
bool bfs(int x, int y)
{
	queue<PII> q;
	q.push(PII(x, y));
	vis[x][y] = 1;
	while(!q.empty())
	{
		PII cur = q.front();
		q.pop();
		for(int i=0; i<4; ++i){
			int nx = cur.fi+dx[i];
			int ny = cur.se+dy[i];
			if(nx<1 || nx>n || ny<1 || ny>m)  continue;
			if(a[nx][ny]='#')  continue;
			if(vis[nx][ny])  continue;
			vis[nx][ny] = 1;
			q.push(PII(nx,ny));
		}
	}
	
	bool ex=1;
	for(int i=1; i<=n&&ex; ++i)
		for(int j=1; j<=m; ++j)
		if(a[i][j]=='G' && vis[i][j]==0) {
			ex = 0;
			break;
		}
		
	return ex;
}
 
void solve()
{
	scanf("%d %d", &n,&m);
	memset(a,0,sizeof(a));
	memset(vis,0,sizeof(vis));
	for(int i=1; i<=n; ++i)  scanf(" %s", a[i]+1);
	
	bool G=0,ex=1;
	for(int i=1; i<=n; ++i) {
		for(int j=1; j<=m; ++j) {
			if(a[i][j] == 'B') {
				for(int k = 0; k < 4; ++k){
					if(a[i+dx[k]][j+dy[k]]=='.')	a[i+dx[k]][j+dy[k]]='#';
					else if(a[i+dx[k]][j+dy[k]]=='G')	ex=0;
				}
			}
			else if(a[i][j]=='G')  G=1;
		}
	}
	
	if(ex==0 || (G!=0 && a[n][m]=='#'))  printf("No\n");
	else {
		if(G==0)  printf("Yes\n");
		else {
			ex = bfs(n,m);
			printf("%s\n", ex ? "Yes":"No");
		}
	}
	
}
 
int main()
{
	cin>>t;
	while(t--)  solve();
	return 0;
}

E. Maximum Subsequence Value

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Ridhiman challenged Ashish to find the maximum valued subsequence of an array a of size n consisting of positive integers.

The value of a non-empty subsequence of k elements of a is defined as ∑2i over all integers i≥0 such that at least max(1,k−2) elements of the subsequence have the i-th bit set in their binary representation (value x has the i-th bit set in its binary representation if ⌊x2i⌋mod2 is equal to 1).

Recall that b is a subsequence of a, if b can be obtained by deleting some(possibly zero) elements from a.

Help Ashish find the maximum value he can get by choosing some subsequence of a.

Input
The first line of the input consists of a single integer n (1≤n≤500) — the size of a.

The next line consists of n space-separated integers — the elements of the array (1≤ai≤1018).

Output
Print a single integer — the maximum value Ashish can get by choosing some subsequence of a.

Examples
input
3
2 1 3
output
3
input
3
3 1 4
output
7
input
1
1
output
1
input
4
7 7 1 1
output
7

Note
For the first test case, Ashish can pick the subsequence {2,3} of size 2. The binary representation of 2 is 10 and that of 3 is 11. Since max(k−2,1) is equal to 1, the value of the subsequence is 20+21 (both 2 and 3 have 1-st bit set in their binary representation and 3 has 0-th bit set in its binary representation). Note that he could also pick the subsequence {3} or {2,1,3}.

For the second test case, Ashish can pick the subsequence {3,4} with value 7.

For the third test case, Ashish can pick the subsequence {1} with value 1.

For the fourth test case, Ashish can pick the subsequence {7,7} with value 7.

题意:有点难解释…粗略解释一下:给定一个数组a,要求选出具有最大价值的子序列。假设此子序列的长度为k,那么最大价值的计算方法为:对于这个序列中的所有数的二进制表示,第 i(从0开始)位上是1的数的数量若大于等max(k-2,1),那么价值就可以 += (还没理解的可以借助样例解释)。

思路:子序列的选择其实长度最大为3,再大的话,就不仅仅对答案的贡献不大,还把答案的贡献缩小了。因为序列长度在3以内时都只需要1个数在第 i 位上是1就可以,若长度为4,那么可能会导致一些数位只有一个数满足,而要求的计算价值至少需要两个,这样有可能还会拖累到价值的计算,但是又不会给价值增加答案:对于本身第 i 位已经有1个的,若新增的数第 i 位也有1,对答案不会有增加,对本身第 i 位没有1的,新增的数第 i 位有1,也无法计入答案,因此选择三个以内是可以保证价值的最大化的。由于n只有500,所以可以暴力枚举所有方案,价值的计算就转化为了:对于第 i 位,若有1,则价值+=。而第 i 位上是否有1,直接按位或就能知道枚举的3个数哪里有1了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	LL ans=0;
	vector<LL> a(n);
	for(int i=0; i<n; ++i)	scanf("%lld", &a[i]);
	
	for(int i=0; i<n; ++i)
		for(int j=0; j<n; ++j)
			for(int k=0; k<n; ++k){
				LL tmp;
				tmp = a[k] | a[i] | a[j];
				ans = max(ans,tmp);
			}
			
	printf("%lld\n", ans);
	return 0;
}

F. Swaps Again

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output

Ayush, Ashish and Vivek are busy preparing a new problem for the next Codeforces round and need help checking if their test cases are valid.

Each test case consists of an integer n and two arrays a and b, of size n. If after some (possibly zero) operations described below, array a can be transformed into array b, the input is said to be valid. Otherwise, it is invalid.

An operation on array a is:

select an integer k (1≤k≤⌊n2⌋)
swap the prefix of length k with the suffix of length k
For example, if array a initially is {1,2,3,4,5,6}, after performing an operation with k=2, it is transformed into {5,6,3,4,1,2}.

Given the set of test cases, help them determine if each one is valid or invalid.

Input
The first line contains one integer t (1≤t≤500) — the number of test cases. The description of each test case is as follows.

The first line of each test case contains a single integer n (1≤n≤500) — the size of the arrays.

The second line of each test case contains n integers a1, a2, …, an (1≤ai≤109) — elements of array a.

The third line of each test case contains n integers b1, b2, …, bn (1≤bi≤109) — elements of array b.

Output
For each test case, print “Yes” if the given input is valid. Otherwise print “No”.

You may print the answer in any case.

Example
input
5
2
1 2
2 1
3
1 2 3
1 2 3
3
1 2 4
1 3 4
4
1 2 3 2
3 1 2 2
3
1 2 3
1 3 2
output
yes
yes
No
yes
No

Note
For the first test case, we can swap prefix a[1:1] with suffix a[2:2] to get a=[2,1].

For the second test case, a is already equal to b.

For the third test case, it is impossible since we cannot obtain 3 in a.

For the fourth test case, we can first swap prefix a[1:1] with suffix a[4:4] to obtain a=[2,2,3,1]. Now we can swap prefix a[1:2] with suffix a[3:4] to obtain a=[3,1,2,2].

For the fifth test case, it is impossible to convert a to b.
在这里插入图片描述

#include <bits/stdc++.h>
#define LL long long
#define PII pair<int, int>
using namespace std;
 
int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		int n;
		scanf("%d", &n);
		multiset<PII> msa, msb;
		vector<int> a(n), b(n);
		for(int i=0; i<n; ++i)  scanf("%d", &a[i]);
		for(int i=0; i<n; ++i)  scanf("%d", &b[i]);
		for(int i=0; i<n; ++i) {
			msa.insert(PII(a[i], a[n-i-1]));
			msb.insert(PII(b[i], b[n-i-1]));
		}
		if(msa!=msb)  printf("No\n");
		else  printf("Yes\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值