牛客周赛 Round 79


A. 小红的合数寻找

题意:在[x,2x]中找一个合数。

如果x=1,则输出1,如果x=2,输出4。否则如果x是奇数直接让他加一即可。

点击查看代码
void solve() {
    int x;
    std::cin >> x;
    if (x == 1) {
    	std::cout << -1 << "\n";
    	return;
    }
    if (x == 2) {
    	std::cout << 4 << "\n";
    	return;
    }
    x += x & 1;
    std::cout << x << "\n";
}

B. 小红的小球染色

题意:有n个小球, 每次随机选择两个相邻的球染色. 问最少操作数和最多操作数.

要让操作数最小, 那么我们每三个球里选右边两个染色即可保证让最多的球不被染色, 进而操作数最少, 答案为n3+(n%3==2).
最多操作就是相邻两个两个选, 可以选n2个.

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::cout << (n / 3 + (n % 3 == 2)) << " "  << n / 2 << "\n";
}

C. 小红的二叉树

题意: 求一棵满二叉树里有多少长度为2的简单路径.

高度为1个数为0, 高度为2则是1. 高度为3每个点都可以向上两次贡献一条路径, 以及每两个点可以通过父亲贡献一条路径。模拟累加即可。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    if (n == 1) {
    	std::cout << 0 << "\n";
    	return;
    }

    if (n == 2) {
    	std::cout << 1 << "\n";
    	return;
    }

    Z ans = 1;
    Z num = 4;
    for (int i = 3; i <= n; ++ i) {
    	ans += num + num / 2;
    	num *= 2;
    }

    std::cout << ans << "\n";
}

D. 小红的“质数”寻找

题意:在[x,2x]中找一个数位和是质数的数。

这题正解是分类讨论,最高位为1则输出"2"+n1个0,为2输出"3"+n1个0。类似的可以得出其他情况的解。我写了个模拟,因为数位和最多1e6左右的数量级,而质数的出现相对来说是比较频繁的,模拟加法然后判断就行。(不过考虑有进位的影响,每次加一并不一定导致数位和增加,所以我这个做法不太严谨,赛时跑了三百多ms,可能是数据水了)。

点击查看代码
const int N = 2e7 + 6;

std::vector<int> primes;
bool st[N];
void init(int n) {
	st[1] = 1;
	for (int i = 2; i <= n; ++ i) {
		if (!st[i]){
			primes.push_back(i);
		}

		for (auto & p : primes) {
			if (p * i > n) {
				break;
			}

			st[p * i] = true;
			if (i % p == 0) {
				break;
			}
		}
	}
}

void solve() {
    std::string s;
    std::cin >> s;
   	std::reverse(s.begin(), s.end());

   	auto check = [&]() -> bool {
   		int sum = 0;
   		for (auto & c : s) {
   			sum += c - '0';
   		}

   		return !st[sum];
   	};

   	int t = 1;
   	for (auto & c : s) {
   		t += c - '0';
   	}

   	while (t -- ) {
   		if (check()) {
   			std::reverse(s.begin(), s.end());
   			std::cout << s << "\n";
   			return;
   		}

   		for (int i = 0; ; ++ i) {
   			if (i >= s.size()) {
   				s.push_back('1');
   				break;
   			} 

   			if (s[i] == '9') {
   				s[i] = '0';
   			} else {
   				s[i] += 1;
   				break;
   			}
   		}
   	}

   	std::cout << -1 << "\n";
}


int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	init(2e6);
	int T = 1; std::cin >> T;
	while (T -- ) {
		solve();
	} 
	return 0;
}

E. 小红的好排列

题意:求所以长度为n的排列中有多少个满足(pi×i)%3==0的位置恰好有n2个。

对于i%3==0的位置,不管放什么数都是3的倍数,那么我们还需要n2n3个位置是满足条件。那么我们要从所有三的倍数里选出n2n3个放在其余nn3个位置,然后其余的n3(n2n3)个三的倍数必须要放在i%3==0的位置,然后其他数随便放。
a=n2n3,b=n3(n2n3)
答案为C(n3,a)×C(nn3,a)×a!×C(n3,b)×b!×(nn3)!

点击查看代码
void solve() {
    int n;
    std::cin >> n;

    if (n / 3 + n / 3 < n / 2) {
    	std::cout << 0 << "\n";
    	return;
    }

    std::vector<Z> fact(n + 1);
    fact[0] = 1;

    for (int i = 1; i <= n; ++ i) {
    	fact[i] = fact[i - 1] * i;
    }

    auto C = [&](int n, int m) -> Z {
    	if (n < m) {
    		return 0;
    	}

    	return fact[n] / fact[m] / fact[n - m];
    };

    int a = n / 2 - n / 3, b = n / 3 - (n / 2 - n / 3);
    Z ans = C(n / 3, a) * C(n - n / 3, a) * fact[a] * C(n / 3, b) * fact[b] * fact[n - n / 3];
    std::cout << ans << "\n";
}

F. 小红的小球染色期望

题意:有n个小球, 每次随机选择两个相邻的球染色。 问操作数的期望。

fi为有i个小球时的期望,则答案为fn
考虑如何求fi,发现操作一次后,相当于把操作位置的两边断开了,左右两边不可能有一起操作的情况,所以可以求左边的期望和右边的期望的和,就是操作个数的期望。n1的位置每个位置有1n概率操作到,那么所有情况的期望为j=1i11i1(f[j1]+f[n(j+1)])+1=21i1j=1i2f[j]+1

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    if (n == 1) {
    	std::cout << 0 << "\n";
    	return;
    }

    std::vector<Z> f(n + 1), sum(n + 1);
    f[2] = sum[2] = 1;
    for (int i = 3; i <= n; ++ i) {
    	f[i] = (Z)1 / (Z)(i - 1) * 2 * sum[i - 2] + 1;
    	sum[i] = sum[i - 1] + f[i];
    }
    std::cout << f[n] << "\n";
}
posted @   maburb  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示