#742 div2 B 思维 C 思维 D 思维 (纯思维场

本文讨论了两种优化算法:B.MEXorMixup通过异或操作找到最优数选择,以及C.CarryingConundrum中Alice的加法策略,涉及奇偶位拆分和最大值求解。D.ExpressionEvaluationError则关注将数字转换进制以最大化和值。
摘要由CSDN通过智能技术生成

B. MEXor Mixup
首先我们肯定要选 [ 0 , a − 1 ] [0,a-1] [0,a1] 区间内的 a a a 个数,然后用 0 0 0 a − 1 a-1 a1 的异或和判断还需要添加几个数。
0 0 0 a − 1 a-1 a1 异或和 为 x x x ,如果 x x x^ b = a b=a b=a,但是我们不能选 a a a,所以可以再选两个数,这两个数异或为 a a a,其他情况只需要添加一个数即 x x x^ b b b
注意:^ 运算符级别小 ==,所以我们要写成 ( x (x (x^ b ) b) b),还有一点就是预处理异或和,否则会 tle。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 3e5 + 9;
const ll mod = 1e9 + 7;
ll n, m;
ll sum[maxn];
void work()
{
	ll a, b;
	cin >> a >> b;
	ll ans = 0;
	ans += a - 1;
	if(sum[a-1] == b) cout << a << endl;
	else
	{	
		if((sum[a-1] ^ a) == b)
			cout << a + 2 << endl;
		else cout << a + 1 << endl;
	}
}

int main()
{
	ios::sync_with_stdio(0);
	for(int i = 1; i <= maxn - 9; ++i)
		sum[i] = sum[i-1] ^ i;
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
/*
0 1 
*/

C. Carrying Conundrum
Alice的加法,其实可以看做,奇数位加奇数位的,偶数位加偶数位的。
因此可以奇偶位分开考虑,他们互不影响
(想不到啊,太奇妙了
注意最后要减去2
当 0,a 和 0,b 组合时,加法上边是 0,下边是 a + b,题目要求两个相加的数是正数
同理,a,0 和 b,0 的情况也要删去

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 3e5 + 9;
const ll mod = 1e9 + 7;
ll n, m;

void work()
{
	string s;
	cin >> s;
	n = s.size();
	int a = 0, b = 0;
	for(int i = 0; i < n; ++i)
		if(i & 1) b = b * 10 + (s[i] - '0');
		else a = a * 10 + (s[i] - '0');
	cout << (a + 1) * (b + 1)  - 2 << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}

D. Expression Evaluation Error
题意:给你一个和 s s s和一个数字 n n n,要把 s s s 分成 n n n 个数的和,然后把每个数当成 11 11 11 进制加和,加完再转化成 10 10 10 进制,要求最后的数尽可能的大。
思路:
考虑到 11 11 11 进制进位需要的数比 10 10 10 进制多 1 1 1,如果 n n n 个数在 11 11 11 进制加和的过程中发生了进位,那么这个和在 10 10 10 进制形式来看肯定是小于 s s s 的,如果我们不进位,就能让加和仍为 s s s ,这样就再转化成 10 10 10 进制就能得到最大值。
比如 s = 80 s=80 s=80 ,拆成 3 3 3 个数,在 11 11 11 进制加和下,如果让不发生进位,那么加起来仍为 80 80 80,如果发生进位,那么就会小于 80 80 80,变成 78 78 78 之类的,显然不进位再转化成 10 10 10 进制得到的大。

构造思路就是前 n − 1 n-1 n1 个采用 10 10 10 的倍数,最后输出剩余的即可

code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 9;
const ll mod = 1e9 + 7;
ll n, m, s;

void work()
{
	cin >> s >> n;
	ll p = 1e9;
	while(n > 1)
	{
		while(s - p < n - 1) p /= 10;
		cout << p << " ";
		s -= p;
		--n;
	}
	cout << s << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值