2020牛客寒假算法基础集训营1

有一天,kotori发现了一个和lovelive相似的游戏:bangdream。令她惊讶的是,这个游戏和lovelive居然是同一个公司出的!
kotori经过一段时间的练习后已经变得非常触,每个音符 x%x% 的概率perfect,获得 分, (100 -x)%(100−x)% 概率great,获得 分。
已知一首歌有 个音符。kotori想知道,不考虑连击加成的话,一首歌得分的期望是多少?

输入描述:
一行 个整数,用空格隔开。分别是 。
输出描述:
一首歌得分的期望,保留两位小数。

思路:只要知道数学期望的概念即可 期望是试验中每次可能结果的概率乘以其结果的总和 也就是概率x结果x实验总数

#include <bits/stdc++.h>

using namespace std;
typedef long long LL ;

const int N = 1005;
const int mod = 1e9+7;

int main()
{
    double n,x,a,b;

    cin >> n >> x >> a >> b;

    x /= 100;
    double y = 1-x;

    double res = n*x*a + n*y*b;

    printf("%.2f\n",res);

    return 0;
}

hanayo很喜欢吃米饭。
有一天,她拿出了 个碗,第一个碗装了 粒米饭,第二个碗装了 粒米饭,以此类推,第 个碗装了 粒米饭。
然而,爱搞恶作剧的rin把所有的碗的顺序打乱,并拿走了一个碗。hanayo想知道,rin拿走的碗里有多少粒米饭?
输入描述:
第一行输入一个正整数 。代表原始的总碗数。
第二行输入 个正整数 a_{i}a
i

,代表目前每碗里米饭数量。
保证输入合法。

输出描述:
输出一个正整数,代表rin拿走的碗里米饭数量。

思路 前n项和-总和即可 记得开LL
这边的n也需要开LL 不然计算的时候就已经爆了

#include <bits/stdc++.h>

using namespace std;
typedef long long LL ;

const int N = 1005;
const int mod = 1e9+7;

int main()
{

    LL n;

    cin >> n;

    LL sum = 0;

    for(int i=0;i<n-1;i++)
    {
        LL x;
        cin >> x;
        sum += x;
    }

    LL s = n+(n*(n-1))/2;

    cout << s - sum << '\n';

    return 0;
}

链接:https://ac.nowcoder.com/acm/contest/3002/E
来源:牛客网

rin最近喜欢上了数论。
然而数论实在太复杂了,她只能研究一些简单的问题。
这天,她在研究正整数因子个数的时候,想到了一个“快速迭代”算法。设 为 的因子个数,将 迭代下去,rin猜想任意正整数最终都会变成 。
例如: 。
她希望你帮她验证一下。她会给你一个正整数 ,让你输出它在迭代过程中,第一次迭代成 的迭代次数。

输入描述:
一个正整数
输出描述:
一个正整数,为 迭代至 的次数。
示例1
输入

复制
12
输出

复制
4
说明

12的因子:1,2,3,4,6,12。共6个。
6的因子:1,2,3,6。共4个。
4的因子:1,2,4。共3个。
3的因子:1,3。共2个。
12 → 6 → 4 → 3 → 2 , 故迭代了4次。

其实就是一个暴力 复杂度O(sqrt(n)) 记录一个球求因子个数的板子

#include <bits/stdc++.h>

using namespace std;
typedef long long LL ;

const int N = 1005;
const int mod = 1e9+7;

LL f(LL x)
{
    LL sum = 0,i;

    for(i = 1; i*i < x ; i++)///计算至sqrt即可
    {
        if(x%i == 0)
           sum += 2;
    }

    return sum+(i*i == x);///完全平方根
}

int main()
{
    LL x;

    int res = 0;

    cin >> x;

    while(x != 2)
        x = f(x),res++;

    cout << res << '\n';

    return 0;
}

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

eli拿到了一个仅由小写字母组成的字符串。
她想截取一段连续子串,这个子串包含至少 个相同的某个字母。
她想知道,子串的长度最小值是多少?
注:所谓连续子串,指字符串删除头部和尾部的部分字符(也可以不删除)剩下的字符串。例如:对于字符串\mathit{“arcaea”}“arcaea”而言,\mathit{“arc”}“arc”、\mathit“rcae”“rcae”都是其子串。而\mathit“car”“car”、\mathit“aa”“aa”则不是它的子串。
输入描述:
第一行输入两个正整数 和
输入仅有一行,为一个长度为 的、仅由小写字母组成的字符串。
输出描述:
如果无论怎么取都无法满足条件,输出 。
否则输出一个正整数,为满足条件的子串长度最小值。
示例1
输入

复制
5 2
abeba
输出

复制
3
说明

选择\mathit“beb”“beb”子串,长度为3,其中包含相同的两个’b’

题意:求最小子串长度 子串中至少包括k个相同的字母
思路:处理26个字母的前缀 维护最小值

#include <bits/stdc++.h>
 
using namespace std ;
 
vector <int> a[30];
 
const int INF = 0x3f3f3f3f ;
 
char s[200005];
 
int main()
{
    int n,k ;
 
    cin >> n >> k;
 
    cin >> s ;
 
    for(int i = 0; i < n;i ++)
       a[s[i]-'a'].push_back(i);///i为位置
 
    int res = INF;
 
    for(int i = 0;i < 26; i ++)
    {
        for(int j = 0;j < a[i].size() ; j ++)
        {
            if(a[i].size()-j < k)///长度已经不及k  直接退出
                break;
 
            res = min(res,a[i][k-1+j] - a[i][j] + 1);///求长度
        }
    }
 
    if(res == INF)
        res = -1;
 
    cout << res << '\n';
 
    return 0;
}

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

nozomi看到eli在字符串的“花园”里迷路了,决定也去研究字符串问题。
她想到了这样一个问题:
对于一个 \mathit{“01”}“01”串而言,每次操作可以把 \mathit00 字符改为 \mathit11 字符,或者把 \mathit11 字符改为 \mathit00 字符。所谓\mathit{“01”}“01”串,即只含字符 \mathit00 和字符 \mathit11 的字符串。
nozomi有最多 次操作的机会。她想在操作之后找出一个尽可能长的连续子串,这个子串上的所有字符都相同。
nozomi想问问聪明的你,这个子串的长度最大值是多少?
注: 次操作机会可以不全部用完。
如果想知道连续子串的说明,可以去问问eli,nozomi不想再讲一遍。
输入描述:
第一行输入两个正整数 和
输入仅有一行,为一个长度为 的、仅由字符 \mathit00 和 \mathit11 组成的字符串。
输出描述:
一个正整数,为满足条件的子串长度最大值。
示例1
输入

复制
5 1
10101
输出

复制
3
说明

只有 次操作机会。
将第二个位置的 \mathit00 改成 \mathit11 ,字符串变成 \mathit{11101}11101,可以选出 \mathit{“111”}“111”子串,长度为 。
如果修改第三个或者第四个位置的字符也可以选出长度为 的子串。

题意:对于01串可以修改k次 求最长子串且子串字符全部相同
思路:双指针尺取

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>

using namespace std;
typedef long long LL ;

#define fi first
#define se second

const int INF = 0x3f3f3f3f;
const double eps = 1e-2;
const double pi=acos(-1);

const int N = 1e4+5;
const int mod = 1e9+7;

int main()
{
    int n,m;

    cin >> n >> m;

    string s;

    cin >> s;

    int l , r;

    l = r = 0;///两个指针
    int sum = 0;///为更改次数
    int res = 0;

    while(r != n)///当尾指针未到数组末尾
    {
        while(sum < m && r < n)///尾指针移动
        {
            if(s[r] == '0')///遇到0更新成1 并且使得更新次数增加
                sum ++ ;
            r ++ ;
        }

        while(s[r] != '0' && r < n)///如果还有连续为1的则继续移动
            r ++ ;

        if(s[l] == '0')///头指针如果为0 则舍去
            sum -- ;

        res = max(res,r-l);///求最大合法答案

        l ++ ;
    }

    printf("%d\n",res);

    return 0;
}

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

nico平时最喜欢说的口头禅是niconiconi~。
有一天nico在逛著名弹幕网站"niconico"的时候惊异的发现,n站上居然有很多她的鬼畜视频。其中有一个名为《让nico为你洗脑》的视频吸引了她的注意。
她点进去一看,就被洗脑了:“niconicoh0niconico*^vvniconicoG(vniconiconiconiconiconicoG(vniconico…”
弹幕中刚开始有很多“nico1 nico2”等计数菌,但到后面基本上都是“计数菌阵亡”的弹幕了。
nico也想当一回计数菌。她认为:“nico” 计 分,“niconi” 计 分,“niconiconi” 计 分。
她拿到了一个长度为 的字符串,请帮她算出最大计数分数。
注:已被计数过的字符不能重复计数!如"niconico"要么当作"nico"+“nico"计 分,要么当作"niconi”+"co"计 分。
输入描述:
第一行四个正整数 。
第二行是一个长度为 的字符串。
输出描述:
一个整数,代表最大的计数分数。
示例1
输入

复制
19 1 2 5
niconiconiconiconi~
输出

复制
7
说明

“niconi"co"niconiconi”~
故为2+5=7分

思路:不同的字符串对应不同的分数 分类dp即可

#include <bits/stdc++.h>

using namespace std ;

typedef long long LL ;

LL dp[300005];

int main()
{
    int n,a,b,c;

    cin >> n >> a >> b >> c;

    string s,t;

    s.push_back(1);

    cin >> t;

    s += t;

    string s1 = "nico";
    string s2 = "niconi";
    string s3 = "niconiconi";
    s[n+1] = '\0';

    for(int i=1; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        if(i>=4 && s.substr(i-3,4) == s1)
            dp[i] = max(dp[i],dp[i-4] + a);
        if(i>=6 && s.substr(i-5,6) == s2)
            dp[i] = max(dp[i],dp[i-6] + b);
        if(i>=10 && s.substr(i-9,10) == s3)
            dp[i] = max(dp[i],dp[i-10] + c);
    }

    cout << dp[n] << '\n';

    return 0;
}

这里提一下substr的用法 s.substr(pos,n) 会返回一个坐标从pos开始 长度为 n 的子串 特别的 若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值