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

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

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

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

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

D. 最小生成树(思维)

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

#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. 连通块计数(组合数学)

题意 : 题面想描述的奇怪的树如下图。我画的这棵树有四条链,每条链有三到四个点。现在给定 nn 条链,每条链上 aia_i 个点,问有多少个非空的连通子树。(结果对 998244353998244353 取模)
牛客国庆集训派对Day4(A D I J)
思路:
1.排除根节点,显然每条链有 Cai+12C_{a_i+1} ^2 种。可以这样理解,在叶节点加上一条链,算上与根节点连接的链,任取两条切断,得到一种非空子树。
2.加上根节点,每条链都有 ai+1a_i + 1 种切法,每次每条链切一刀都可以组成一种可能,所以共有 i=1nai+1\prod _{i=1} ^{n} a_i+1 种可能。
综上:ans=i=1nCai+12+i=1nai+1ans = \sum _{i=1} ^{n} C_{a_i+1} ^2 + \prod _{i=1} ^{n} a_i+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;	
}

相关文章:

  • 2021-06-15
  • 2021-07-19
  • 2021-10-26
  • 2021-11-03
  • 2021-10-03
  • 2021-10-25
  • 2022-02-14
  • 2022-01-20
猜你喜欢
  • 2022-01-04
  • 2021-05-15
  • 2022-12-23
  • 2021-04-22
  • 2021-08-24
  • 2021-04-26
  • 2021-09-06
相关资源
相似解决方案