代码部落 20250629 CSP-S复赛 模拟赛

网址:代码部落

一    小小旅行者:

        思路:因为n最大为1e5,所以不能用最短路来做,根据题目可以直接想到:只需求出a与b异或后的值在二进制下1的个数即可:

        那么这时可能有人想到,在前往b的路上,小S会不会先到了一个不存在的点,然后在到达0-n以内的点?   实际上是不会的,只要从低位开始更改(举个栗子:)

输入  53 43 52

10(43)=2(101011)
10(52)=2(110100)
预计答案为 5
演示: 43-->42(101010)-->40(101000)-->44(101100)-->36(100100)-->52
其中并未越界 且答案确实为5

        代码:

#include
using namespace std;
int n,a,b;
void ct(int m){
	int cnt=0;
	while(m){
		if(m%2==1) cnt++;
		m/=2;
	}
	cout<>n>>a>>b;
	int m=a^b;
	ct(m);
	return 0;
}

 二  随机表达式:

        思路:对于某个⽣成的公式,只要出现了⾄少⼀个 + 或者 - ,那就⼀定可以通过把 + 变成 - ,把 - 变成 + 来获得另⼀ 个公式。并且将这两个公式的结果相加后,第⼀个 + / - 后⾯的所有内容将会被正负抵消,对答案没有贡献

        因此,真正对答案有贡献的部分应当是第⼀个 + / - 号之前的连续⼀段的异或和(即第⼀段的连续异或和)。 直接 for 循环枚举第⼀段连续异或的运算最⼤到哪个位置,记录S=A1^A2^…^Ai

        假设 A1~Ai是第⼀段连续异或运算的范围,注意分为两种情况:

        1. i

&nbs

你可能感兴趣的:(代码部落 20250629 CSP-S复赛 模拟赛)