牛客国庆集训派对Day4(A D I J)

25 篇文章 0 订阅
4 篇文章 0 订阅

链接: https://www.nowcoder.com/acm/contest/204#question

A. 深度学习(思维水题)

题意: n n n 组训练数据,每次训练从 n n n 组中随机选出 B B B 组,花费 B B B 秒, n n n 组数据都被选中过就结束。让你合理设置 B B B 使得,使得训练总时间的期望尽可能的小,输出最小期望。
思路: 设置 B = n B = n B=n ,这样一次就能训练完成,训练总时间 n n n ,期望 n n n 。因为训练总时间最小等于 n n n ,所以这样设置的期望一定最小。

#include <bits/stdc++.h>
using namespace std;

int main(int argc, char const *argv[])
{
	int n;
	cin>>n;
	cout<<n<<endl;
	return 0;
}

D. 最小生成树(思维)

题意: 给一个完全无向图,每个点有一个点权 a i a_i ai, 边 ( u , v ) (u, v) (u,v) 的权值是 a u + a v a_u+a_v au+av, 求边权最小的最小生成树的权值和。
思路: 因为边权取决于点权和,那么一个点和点权最小的点连边,他们的边权(点权和)一定是这个点与所有其他点相连的边权中最小的。那么让所有点都与这个有最小的点权的点相连,生成树的边权就一定是最小的,即 a n s = ( n − 2 ) ∗ m i n ( a i ) + ∑ i = 1 n a i ans = (n-2)*min(a_i) + \sum _{i=1} ^{n} a_i ans=(n2)min(ai)+i=1nai

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 100100;

int main(int argc, char const *argv[])
{
	LL n, a[MAXN];
	cin>>n;
	for (int i = 0; i < n; ++i) {
		cin>>a[i];
	}
	LL ans = 0;
	for (int i = 0; i < n; ++i) {
		ans += a[i]; 
	}
	ans += (*min_element(a, a+n)) * (n-2);
	cout<<ans<<endl;
	return 0;
}

I. 连通块计数(组合数学)

题意 : 题面想描述的奇怪的树如下图。我画的这棵树有四条链,每条链有三到四个点。现在给定 n n n 条链,每条链上 a i a_i ai 个点,问有多少个非空的连通子树。(结果对 998244353 998244353 998244353 取模)
奇怪的树
思路:
1.排除根节点,显然每条链有 C a i + 1 2 C_{a_i+1} ^2 Cai+12 种。可以这样理解,在叶节点加上一条链,算上与根节点连接的链,任取两条切断,得到一种非空子树。
2.加上根节点,每条链都有 a i + 1 a_i + 1 ai+1 种切法,每次每条链切一刀都可以组成一种可能,所以共有 ∏ i = 1 n a i + 1 \prod _{i=1} ^{n} a_i+1 i=1nai+1 种可能。
综上: a n s = ∑ i = 1 n C a i + 1 2 + ∏ i = 1 n a i + 1 ans = \sum _{i=1} ^{n} C_{a_i+1} ^2 + \prod _{i=1} ^{n} a_i+1 ans=i=1nCai+12+i=1nai+1

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 100100;
const int MOD = 998244353;

int main(int argc, char const *argv[])
{
	LL n, a[MAXN];
	cin>>n;
	for (int i = 0; i < n; ++i) {
		cin>>a[i];
	}
	LL ans = 1;
	for (int i = 0; i < n; ++i) {
		ans *= (a[i] + 1);
		ans %= MOD;
	} 
	for (int i = 0; i < n; ++i) {
		ans += a[i]*(a[i]+1)/2;
		ans %= MOD;
	}
	cout<<ans<<endl;
	return 0;
}

J. 寻找复读机(模拟水题)

题意: 群里有一些人是复读机,这些人每次发的消息一定和上一条消息一样,第一个人一定不是复读机。给你一份聊天记录,让你从小到大输出所有可能是复读机的人的编号。(注意:问的是所有可能的人,一个人没说过话,也可能是复读机)

#include <bits/stdc++.h>
using namespace std;
const int MAXM = 1100;

int main(int argc, char const *argv[])
{
	int n, m, num[MAXM];
	string s[MAXM];
	std::vector<int> v;
	cin>>n>>m;
	for (int i = 0; i < m; ++i) {
		cin>>num[i]>>s[i];
	}
	for (int i = 1; i <= n; ++i) {
		if(i == num[0]) continue;
		bool flag = 1;
		// int cnt = 0; 
		for (int j = 1; j < m; ++j) {
			if(num[j] == i) {
				// cnt++;
				if(s[j] != s[j-1]){
					flag = 0;
					break;
				}
			} 
		}
		if(flag) v.push_back(i);
	}
	int len = v.size();
	for (int i = 0; i < len; ++i) {
		cout<<v[i];
		if(i != len-1) cout<<" ";
	}
	return 0;	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值