Codeforces Round #664 (Div. 2)

A. Boboniu Likes to Color Balls

题意:

总共四个颜色,可以进行的操作是,前三个一人拿一个放到第四个,就相当于前三个都减一,第四个 + 3 +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 nnm的象棋,再给定一个初始点 ( s x , s y ) (s_x,s_y) (sx,sy) ,你可以用车一样行驶到同一行或同一列,要求你遍历象棋中的所有点,输出路径。

S 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 a1a2an b 1 , b 2 , … , b m b_1,b_2,…,b_m b1b2bm。对于每个 i ( 1 ≤ i ≤ n ) i(1≤i≤n) i1in,要求您选择一个 j ( 1 ≤ j ≤ m ) j(1≤j≤m) j1jm,并让 c i = a i & b j c_i=a_i\&b_j ci=ai&bj,其中 & \& & 表示按位与运算。请注意,您可以为不同的i选择相同的 j j j。找到最小可能的 c 1 ∣ c 2 ∣ … ∣ c n c_1 | c_2 |…| c_n c1c2cn,其中 ∣ | 表示按位或运算。

a a a b 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 m 的接下来 d d d 天就不能拿了,拿小于 m m m 的还可以继续操作,就可以拿的最大值。

把大于 m m m 和小于 m m m 的分组,选 x x x个大于 m m m 的,肯定拿 x x x个快乐因子最大的,其中有一个在第 n n n 天放,只需要消耗 1 1 1天,所以此时消耗了 ( x − 1 ) ∗ ( d + 1 ) + 1 (x−1)∗(d+1)+1 (x1)(d+1)+1 天。对于选取 x x x个大于 m m 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值