Codeforces Round #664 (Div. 2)

A. Boboniu Likes to Color Balls

题意:

总共四个颜色,可以进行的操作是,前三个一人拿一个放到第四个,就相当于前三个都减一,第四个 + 3 +3 。然后得到的四个数,每个数对应一种字符的个数,问这些字符是否能构成回文串。

构成回文串的情况可以是

  • 个数为偶数的有四个,
  • 或者个数为偶数的有三个为奇数的有一个。
  • 还有就是全部都为奇数,然后经过一次操作前三个颜色都变成了偶数,最后一个颜色也变成了偶数,
  • 然后就是三个奇数的情况,假设前三个里面俩奇数一个偶数,最后那个是奇数,通过一次操作可以把前三个变成俩偶数一个奇数,最后那个变成偶数,假如前三个都是奇数,一次操作,前三个变成偶数最后的变成奇数。

AC代码:

const int N = 2e5 + 50;
int n, m;
int a[N];
int main()
{
 
	int t;
	sd(t);
	while (t--)
	{
		int x = 0, y = 0;
		rep(i, 1, 4)
		{
			cin >> a[i];
			if (a[i] % 2)
				y++;
			else
				x++;
		}
		if (x == 4 || x == 3 || ((y == 4 || y == 3) && (a[1] && a[2] && a[3])))
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}

B. Boboniu Plays Chess

题意:

给你 n n m n∗nm 的象棋,再给定一个初始点 ( s x , s y ) (s_x,s_y) ,你可以用车一样行驶到同一行或同一列,要求你遍历象棋中的所有点,输出路径。

S S 形就行了。

AC代码:

const int N = 2e5 + 10;
const int mod = 1e9 + 7;
int t;
int n, m;
int xx, yy;
int main()
{
	sdd(n, m);
	sdd(xx, yy);
	per(i, yy, 1)
		pdd(xx, i);
	rep(i, yy + 1, m)
		pdd(xx, i);
	int cnt = 0;
	rep(i, xx + 1, n)
	{
		if (cnt & 1)
		{
			rep(j, 1, m)
				pdd(i, j);
		}
		else
		{
			per(j, m, 1)
				pdd(i, j);
		}
		cnt++;
	}
	per(i, xx - 1, 1)
	{
		if (cnt & 1)
		{
			rep(j, 1, m)
				pdd(i, j);
		}
		else
		{
			per(j, m, 1)
				pdd(i, j);
		}
		cnt++;
	}
	return 0;
}

C. Boboniu and Bit Operations

题意:

给出了两个非负整数序列 a 1 a 2 a n a_1,a_2,…,a_n b 1 b 2 b m b_1,b_2,…,b_m 。对于每个 i 1 i n i(1≤i≤n) ,要求您选择一个 j 1 j m j(1≤j≤m) ,并让 c i = a i & b j c_i=a_i\&b_j ,其中 & \& 表示按位与运算。请注意,您可以为不同的i选择相同的 j j 。找到最小可能的 c 1 c 2 c n c_1 | c_2 |…| c_n ,其中 | 表示按位或运算。

a a b b 匹配的所有可能都记录下来,枚举全部情况。

AC代码:

const int N = 2e2 + 50;
int n, m;
int a[N], b[N], bas[N][1027], vis[N][1027];
int len;

int main()
{

	int t;
	sdd(n, m);
	rep(i, 1, n)
		sd(a[i]);
	rep(j, 1, m)
		sd(b[j]);
	rep(i, 1, n)
	{
		rep(j, 1, m)
		{
			bas[i][a[i] & b[j]] = 1;
		}
	}
	len = 1 << 9;
	vis[0][0] = 1;
	rep(i, 1, n)
	{
		rep(j, 0, len)
		{
			if (!bas[i][j])
				continue;
			rep(k, 0, len - 1)
			{
				if (!vis[i - 1][k])
					continue;
				vis[i][k | j] = 1;
			}
		}
	}
	rep(i, 0, len - 1)
	{
		if (vis[n][i])
		{
			pd(i);
			break;
		}
	}
	return 0;
}

D. Boboniu Chats with Du

题意:

给出一个序列,拿大于 m m 的接下来 d d 天就不能拿了,拿小于 m m 的还可以继续操作,就可以拿的最大值。

把大于 m m 和小于 m m 的分组,选 x x 个大于 m m 的,肯定拿 x x 个快乐因子最大的,其中有一个在第 n n 天放,只需要消耗 1 1 天,所以此时消耗了 ( x 1 ) ( d + 1 ) + 1 (x−1)∗(d+1)+1 天。对于选取 x x 个大于 m m 的先预处理出来需要几天,然后枚举选取小于 m m 的,找最大值。

AC代码:

const int N = 2e5 + 50;
int n, d, m;
ll da[N], xiao[N];
ll sum[N], sumb[N];
int cnt1, cnt2, pos;
ll ans;

bool cmp(int a, int b)
{
	return a > b;
}

int main()
{
	sddd(n, d, m);
	cnt1 = 0, cnt2 = 0;
	rep(i, 1, n)
	{
		ll x;
		sld(x);
		if (x > m)
			da[++cnt1] = x;
		else
			xiao[++cnt2] = x;
	}
	sort(da + 1, da + 1 + cnt1, cmp);
	sort(xiao + 1, xiao + 1 + cnt2, cmp);
	pos = 0;
	rep(i, 1, n)
	{
		sum[i] = sum[i - 1];
		if ((i % (d + 1)) == 1 && pos + 1 <= cnt1)
			sum[i] += da[++pos];
	}
	rep(i, 1, cnt2)
		sumb[i] = sumb[i - 1] + xiao[i];
	ans = 0;
	rep(i, 0, cnt2)
		ans = max(ans, sumb[i] + sum[n - i]);
	pld(ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/107973632