Codeforces Round #648 (Div. 2)

A. Matrix Game

先统计可以填的行数和列数,每次填行数和列数都会减小 1 1 1 所以只需要判断行数和列数最小值的奇偶性即可。

AC代码:

int n, m, k;
bool r[110], c[110];
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sdd(n, m);
		mem(r, 0);
		mem(c, 0);
		rep(i, 1, n)
		{
			rep(j, 1, m)
			{
				int x;
				sd(x);
				if (x)
					r[i] = c[j] = true;
			}
		}
		int a = 0, b = 0;
		rep(i, 1, n)
		{
			if (!r[i])
				a++;
		}
		rep(i, 1, m)
		{
			if (!c[i])
				b++;
		}
		if (min(a, b) & 1)
			puts("Ashish");
		else
			puts("Vivek");
	}
	return 0;
}

B. Trouble Sort

0 0 0 1 1 1 如果都存在的话那么肯定是可以的,因为有可以置换的话,就可以通过不断的交换位置把每个数换到自己本来的位置。然后再判断只有 0 0 0 或者只有 1 1 1 的是否为递增即可。

AC代码:

int n, m, k;
int a[1100], b[1100];
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sd(n);
		bool flag = false, ok = false;
		rep(i, 1, n)
			sd(a[i]);
		rep(i, 1, n)
		{
			sd(b[i]);
			if (b[i])
				flag = true;
			else
				ok = true;
		}
		if (flag && ok)
		{
			puts("Yes");
			continue;
		}
		flag = true;
		rep(i, 2, n)
		{
			if (a[i] < a[i - 1])
			{
				flag = false;
				break;
			}
		}
		if (flag)
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}

C. Rotation Matching

用一个数组存一下上面和下面相同的数字的位置差,然后找每个位置差可以产生的最大匹配数。

AC代码:

const int N = 5e5 + 50;
int n, m, k;
int a[N], b[N], pos[N], cnt[N];
int main()
{
	int T;
	sd(n);
	rep(i, 1, n)
		cnt[i] = 0;
	rep(i, 1, n)
		sd(a[i]),
		pos[a[i]] = i;
	rep(i, 1, n)
		sd(b[i]);
	rep(i, 1, n)
	{
		if (pos[b[i]] < i)
			cnt[pos[b[i]] + n - i]++;
		else
			cnt[pos[b[i]] - i]++;
	}
	int ans = 0;
	rep(i, 0, n)
		ans = max(ans, cnt[i]);
	pd(ans);
	return 0;
}

D. Solve The Maze

首先把坏人相邻的空格变成障碍物,因为好人肯定不会经过坏人周围的空格,否则坏人会顺着这个路逃走,然后找每一个好人是否可以走出去。好人如果和坏人紧挨着或者 n , m n,m n,m 位置是墙,那么肯定不行,好人如果数量为 0 0 0 这样输出 Y e s Yes Yes

AC代码:

const int N = 5e5 + 50;
int n, m;
char c[100][100];
int vis[100][100];
int mp[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
 
void bfs()
{
	queue<PII> q;
	vis[n][m] = 1, q.push(PII(n, m));
	while (!q.empty())
	{
		PII now = q.front();
		q.pop();
		rep(i, 0, 3)
		{
			int dx = now.fi + mp[i][0], dy = now.se + mp[i][1];
			if (dx < 0 || dx > n || dy < 0 || dy > m || c[dx][dy] == '#' || vis[dx][dy] != -1)
				continue;
			vis[dx][dy] = 1, q.push(PII(dx, dy));
		}
	}
}
 
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sdd(n, m);
		rep(i, 1, n)
			ss(c[i] + 1);
		int cnt = 0;
		rep(i, 1, n)
		{
			rep(j, 1, m)
			{
				if (c[i][j] == 'G')
					cnt++;
			}
		}
		if (!cnt)
		{
			puts("Yes");
			continue;
		}
		bool flag = true;
		rep(i, 1, n)
		{
			rep(j, 1, m)
			{
				if (c[i][j] == 'B')
				{
					rep(t, 0, 3)
					{
						int dx = i + mp[t][0], dy = j + mp[t][1];
						if (dx < 0 || dx > n || dy < 0 || dy > m || c[dx][dy] == 'B')
							continue;
						if (c[dx][dy] == 'G')
						{
							flag = false;
							break;
						}
						c[dx][dy] = '#';
					}
				}
				if (!flag)
					break;
			}
			if (!flag)
				break;
		}
		if (!flag || c[n][m] == '#')
		{
			puts("No");
			continue;
		}
		rep(i, 1, n)
		{
			rep(j, 1, m)
				vis[i][j] = -1;
		}
		bfs();
		flag = true;
		rep(i, 1, n)
		{
			rep(j, 1, m)
			{
				if (c[i][j] == 'G' && vis[i][j] != 1)
				{
					flag = false;
					break;
				}
			}
		}
		if (flag)
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}

E. Maximum Subsequence Value

首先肯定从最高位开始选,假设最高位是 h h h 且有 x x x 个数含有 2 h 2^h 2h

如果 x > = 3 x >= 3 x>=3 那么你以后无论再选什么数 都会造成 对于第 j j j ( 2 j ) (2^j) (2j) c n t + 1 , x + 1 cnt + 1, x + 1 cnt+1,x+1, 本质上 m a x ( 1 , x − 2 ) > c n t max(1, x - 2) > cnt max(1,x2)>cnt 没变

所以我们要卡住 k < = 3 k <= 3 k<=3, 找最大值就行了。

AC代码:

int n, m, k;
ll a[N];
int main()
{
	int t;
	sd(n);
	rep(i, 1, n)
		sld(a[i]);
	ll ans = a[1];
	rep(i, 1, n)
	{
		rep(j, i, n)
		{
			rep(k, j, n)
				ans = max(ans, a[i] | a[j] | a[k]);
		}
	}
	pld(ans);
	return 0;
}

F. Swaps Again

很显然,对于对称的两个数 ( a i 和 a n − i + 1 ) (a_i 和 a_{n−i+1}) aiani+1,经过任意操作后,它俩还是对称的,就是只能和对称位置的交换,只要把对称的数捆绑在一起,然后判断可不可以变成想要的序列即可。

AC代码 :

const int N = 5e2 + 50;
int n, m, k;
int a[N], b[N];
map<PII, int> mp;
int main()
{
	int t;
	sd(t);
	while (t--)
	{
		sd(n);
		rep(i, 1, n)
			sd(a[i]);
		rep(i, 1, n)
			sd(b[i]);
		bool flag = true;
		mp.clear();
		if (n % 2 == 1 && a[(n + 1) / 2] != b[(n + 1) / 2])
		{
			puts("No");
			continue;
		}
		rep(i, 1, n / 2)
		{
			int x = a[i], y = a[n - i + 1];
			if (x > y)
				swap(x, y);
			mp[{x, y}]++;
			x = b[i], y = b[n - i + 1];
			if (x > y)
				swap(x, y);
			mp[{x, y}]--;
		}
		for (auto i : mp)
		{
			if (i.se != 0)
				flag = false;
		}
		if (flag)
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}

你可能感兴趣的:(CodeForces)