牛客网国庆集训派对Day4题目 2018年

链接:https://www.nowcoder.com/acm/contest/204/A
来源:牛客网

深度学习
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
Special Judge, 64bit IO Format: %lld

题目描述

小 A 最近在研究深度学习,他自己搭建了一个很牛逼的神经网络,现在他手头一共有 n 组训练数据,一开始他会给自己的神经网络设置一个 batch size,假设为 B (1≤ B≤ n) ,每次训练他都会从手头的 n 组训练数据中抽取不同的 B 组数据,然后扔到神经网络去训练。
然而小 A 的服务器并不是特别支持并行,所以运行时间和 B 成正比,每一次训练都会花费 B 秒的时间。
现在小 A 发现这样每次随机选数据的话,从概率上讲要训练好多次才能使得每组训练数据都被选中过。小 A 是一个炼丹的新手,他觉得只要所有训练数据都被选中过,那么这个模型就会很牛逼,所以只要某次训练后,如果所有训练数据都被选中过,那么他就会停止进行训练。
现在他想合理地设置 B ,使得训练总时间的期望值尽可能地短,你只需要求出这个最小的期望值。

输入描述:

第一行一个正整数 n

输出描述:

输出一个实数,表示最小的期望值,本题有spj,只要和标准答案的标准误差在 10-3 以内就算正确

示例1

输入

复制
1

输出

复制
1.000000

备注:

1≤ n ≤ 40

思路:浪费时间的总和是大于等于n的,所以求的最小的就是n。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     double n;
 7     scanf("%lf",&n);
 8    printf("%.6f
",n);
 9     return 0;
10 }

链接:https://www.nowcoder.com/acm/contest/204/D
来源:牛客网

最小生成树
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

小 A 有一张 n 个点的带权无向图,这张无向图非常特别,首先第 i 个点有一个点权 ai,之后这张无向图是一张完全图,且边 (u,v) 的权值为 au+av
现在小 A 想找一个这张图的边权之和最小的生成树,需要你来帮帮他

输入描述:

第一行一个正整数 n
第二行 n 个整数 a
1
,a
2
…a
n

输出描述:

输出边权和最小的生成树的边权之和
示例1

输入

复制
3
1 2 3

输出

复制
7

备注:

1≤ n≤ 10
5

0≤ a
i
≤ 10
9

思路:把n-1个点都和根结点相连,求出n-1条边的总和即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+5;
 5 ll a[maxn];
 6 int main()
 7 {
 8     int n;
 9     scanf("%d",&n);
10    for(int i=1;i<=n;i++)
11    {
12        scanf("%lld",&a[i]);
13    }
14    sort(a+1,a+n+1);
15    ll sum=0;
16    for(int i=2;i<=n;i++)
17    {
18         sum+=a[1]+a[i];
19    }
20    printf("%lld
",sum);
21    return 0;
22 }

链接:https://www.nowcoder.com/acm/contest/204/G
来源:牛客网

区间权值
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

小 Bo 有 n 个正整数 a1..an,以及一个权值序列 w1…wn,现在他定义
现在他想知道 的值,需要你来帮帮他
你只需要输出答案对 109+7 取模后的值

输入描述:

第一行一个正整数 n
第二行 n 个正整数 a
1
..a
n

第三行 n 个正整数 w
1
..w
n

输出描述:

输出答案对 10
9
+7 取模后的值
示例1

输入

复制
3
1 1 1
1 1 1

输出

复制
10

备注:

1≤ n≤ 3x 10
5

1≤ a
i
≤ 10
7

1≤ w
i
≤ 10
7
 
思路:前缀和。有对称性。把式子展开找出w1~wn的各个和ai的乘积和。
代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=3e5+5;
 5 const int mod=1e9+7;
 6 int n,pnt;
 7 ll a[maxn],w[maxn],suma[maxn],sumb[maxn];
 8 ll sumc[maxn];
 9 int main()
10 {
11     scanf("%d",&n);
12     for(int i=1; i<=n; i++)
13     {
14         scanf("%lld",&a[i]);
15         suma[i]=suma[i-1]+a[i];
16         suma[i]%=mod;
17     }
18     for(int i=1; i<=n; i++)
19         scanf("%lld",&w[i]);
20     sumb[1]=suma[n];
21     for(int i=2; i<=n; i++)
22     {
23         if(n-i+1>i-1)
24         {
25             sumb[i]=sumb[i-1]+(suma[n-i+1]-suma[i-1]);
26             sumb[i]%=mod;
27         }
28         else
29         {
30             pnt=i-1;
31             break;
32         }
33     }
34     sumb[n]=suma[n];
35     for(int i=n-1; i>=pnt+1; i--)
36     {
37         sumb[i]=sumb[n-i+1];
38     }
39     ll ans=0;
40     for(int i=1; i<=n; i++)
41     {
42         ans+=(sumb[i]%mod*w[i]%mod)%mod;
43         ans%=mod;
44     }
45     ans%=mod;
46     printf("%lld
",ans);
47     return 0;
48 }

链接:https://www.nowcoder.com/acm/contest/204/I
来源:牛客网

连通块计数
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i 条链有 ai 个点,每一条链的一端都与根结点相连。
现在小 A 想知道,这棵长得奇怪的树有多少非空的连通子树,你只需要输出答案对 998244353 取模的值即可

输入描述:

第一行一个正整数 n
第二行 n 个正整数 a
1
…a
n

输出描述:

输出答案对 998244353 取模后的值
示例1

输入

复制
2
1 1

输出

复制
6

备注:

1≤ n≤ 10
5

1≤ a
i
≤ 10
7
 

思路:分为两部分:含有根结点+不含根结点的各个部分和。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+5;
 5 ll a[maxn];
 6 ll b[maxn];
 7 int main()
 8 {
 9     int n;
10     scanf("%d",&n);
11     for(int i=1;i<=n;i++)
12     {
13         scanf("%lld",&a[i]);
14         b[i]=a[i]+1;
15     }
16     sort(b+1,b+n+1);
17     ll he=1;
18     for(int i=1;i<=n;i++)
19     {
20         he=(he*b[i])%998244353;
21     }
22     for(int i=1;i<=n;i++)
23     {
24         he=(he+(a[i]*(a[i]+1)/2%(998244353)))%998244353;
25     }
26     printf("%lld
",he);
27     return 0;
28 }

链接:https://www.nowcoder.com/acm/contest/204/J
来源:牛客网

寻找复读机
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

某个 QQ 群里一共有 n 个人,他们的编号是 1..n,其中有一些人本质上是复读机。
小 A 发现,如果一个人的本质是复读机,那么他每次发的消息一定跟群里的上一条消息一样,特别地第一个发消息的人一定不是复读机。
现在小 A 搞到了一份聊天记录,他想请你找出所有可能是复读机的群友

输入描述:

第一行两个正整数 n,m,表示群里的人数和聊天记录的总条数
接下来 m 行按时间顺序给出聊天记录,每行有一个正整数 x 和一个小写字母字符串 S,表示群友 x 发了消息 S

输出描述:

输出一行,将所有可能是复读机的群友的编号按照从小到大排序后输出,每两个编号之间隔一个空格
示例1

输入

复制
3 5
1 gugugu
2 gugugu
1 gugu
3 tingzhifudu
2 tingzhifudu

输出

复制
2

备注:

1≤ n≤ 10
3

1≤ m≤ 10
3

1≤ |S|≤ 100

思路:用map,strcpy,strcmp,然后找谁不是复读机,输出是复读机的即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
map <int ,int> a;
char s[110],tmp[110];
int x;
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    scanf("%d %s",&x,&s);
    a[x]=1;
    strcpy(tmp,s);
    for(int i=2;i<=m;i++)
    {
        scanf("%d %s",&x,&s);
        if(strcmp(s,tmp)!=0)
        {
            a[x]=1;
        }
        strcpy(tmp,s);
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0)
        {
            printf("%d ",i);
        }
    }
    return 0;
}

链接:https://www.nowcoder.com/acm/contest/204/H
来源:牛客网

树链博弈
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

给定一棵 n 个点的树,其中 1 号结点是根,每个结点要么是黑色要么是白色
现在小 Bo 和小 Biao 要进行博弈,他们两轮流操作,每次选择一个黑色的结点将它变白,之后可以选择任意多个(可以不选)该点的祖先(不包含自己),然后将这些点的颜色翻转,不能进行操作的人输
由于小 Bo 猜拳经常输给小 Biao,他想在这个游戏上扳回一城,现在他想问你给定了一个初始局面,是先手必胜还是后手必胜

输入描述:

第一行一个正整数 n
第二行 n 个整数 w
1
..w
n
,w
i
∈ {0,1},w
i
=1 表示第 i 个结点一开始是黑点,否则是白点
接下来 n-1 行,每行两个正整数 u,v 表示一条树边 (u,v)

输出描述:

如果先手必胜,输出First ,否则输出Second
示例1

输入

复制
2
1 0
1 2

输出

复制
First

备注:

1≤ n≤ 1000

思路:DFS找出每一个点所在的层数,若果每一层的黑色为偶数则输出“Second”。
代码:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int Max = 3e6+10;
 4 vector <int> ma[Max];
 5 int du[Max],deep[Max];
 6 bool visited[Max];
 7 int color[Max];
 8 int n;
 9 #define rep(i,s,n)  for(int i=s;i<=n;i++)
10 #define per(i,n,s)  for(int i=n;i>=s;i--)
11 
12 void DFS(int u, int dp){
13       deep[u]=dp;
14       visited[u]=true;
15       int len=ma[u].size();
16       rep(i,0,len-1){
17            int to=ma[u][i];
18            if(!visited[to]){
19             DFS(to,++dp);
20             dp--;
21            }
22       }
23 }
24 
25 int main(){
26      scanf("%d",&n);
27      rep(i,1,n){
28          scanf("%d",&color[i]);
29      }
30      int u,v;
31      rep(i,1,n-1){
32         scanf("%d %d",&u,&v);
33         ma[u].push_back(v);
34         ma[v].push_back(u);
35      }
36      DFS(1,1);
37      bool  ok=1;
38      rep(i,1,n){
39          if(color[i]){
40             du[deep[i]]++;
41          }
42      }
43      rep(i,1,n){
44         if(du[i]%2==1){
45             ok=0;
46             break;
47         }
48               }
49      if(ok){
50         printf("Second
");
51      }
52      else{
53         printf("First
");
54      }
55      return 0;
56 }
原文地址:https://www.cnblogs.com/weixq351/p/9742740.html