牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) 题解

A-吐泡泡

题目描述
小鱼儿吐泡泡,嘟嘟嘟冒出来。小鱼儿会吐出两种泡泡:大泡泡”O”,小泡泡”o”。
两个相邻的小泡泡会融成一个大泡泡,两个相邻的大泡泡会爆掉。
(是的你没看错,小气泡和大气泡不会产生任何变化的,原因我也不知道。)
例如:ooOOoooO经过一段时间以后会变成oO。
备注:
自左到右进行合并
对于100%的数据,
字符串的长度不超过100。
链接:https://www.nowcoder.com/acm/contest/74/A
题解
用栈。
代码

#include<bits/stdc++.h>
using namespace std;
stack<int>st;
void sol(int j)
{
    if(st.empty()) st.push(j);
    else{
        int k=st.top();
        if(k==0&&j==0){
            st.pop();
            sol(1);
        }else if(k==1&&j==1){
            st.pop();
        }else st.push(j);
    }
}
int main()
{
    char s[105];

    while(~scanf("%s",s)){
        for(int i=0;s[i]!='\0';i++){
            if(s[i]=='o'){sol(0);}
            else{sol(1);}
        }
        stack<char> tt;
        while(!st.empty())//导出
        {
            int k=st.top();st.pop();
            if(k==0) tt.push('o');
            else tt.push('O');
        }
        while(!tt.empty()){//输出
            char k=tt.top();tt.pop();
            printf("%c",k);
        }
        printf("\n");
    }
    return 0;
}

D-YB要打炉石

题目描述
Wozuinb非常喜欢打炉石传说,但是菜的不行,所以他决定打
竞技场来练练手。系统按顺序给出n张卡牌,每张卡牌都有自
己的使用消耗a[i],每次只给出一张,wozuinb可以选择或者
弃掉这张牌。每选择一张牌都会按选择顺序放在卡槽中,当
卡槽中放满30张即可组成一套套牌。Wozuinb希望自己的套牌的
消耗满足一个平滑的曲线,即30张卡牌都满足第i张卡牌的消耗
不小于第i-1张(i>1)。请你帮助wozuinb看一看,这些卡牌能不
能组成想要的套牌,如果能组成输出“yes”,如果不能输出“no”。
链接:https://www.nowcoder.com/acm/contest/74/D
题解
动态规划最长上升子序列(LIS)。注意是子序列长度大于等于30才成立。并且输入不能写多组数据。
代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e5+100;
int a[105],dp[105];
int n;
int main()
{
    scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        dp[1]=a[1];
        int len=1;
        for(int i=2;i<=n;++i){
            if(a[i]>=dp[len])
                dp[++len]=a[i];
            else{
                int pos=lower_bound(dp,dp+len,a[i])-dp;
                dp[pos]=a[i];
            }
        }
        //printf("%d\n",len);
        printf("%s\n",(len>=30)?"yes":"no");

    return 0;
}

E-小G有一个大树

题目描述
小G想要把自己家院子里的橘子树搬到家门口(QAQ。。就当小G是大力水手吧)
可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点。
怎么描述这棵树呢。。。就把它看成由一个个节点构成的树吧。结点数就
代表树重。
链接:https://www.nowcoder.com/acm/contest/74/E
题解
树形DP。
代码

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

int N; // 1<= N <= 20000
const int maxn = 20000;
vector<int> tree[maxn + 5]; // tree[i]表示节点i的相邻节点
int d[maxn + 5]; // d[i]表示以i为根的子树的节点个数
#define INF 10000000
int minNode;
int minBalance;
void dfs(int node, int parent) // node and its parent
{
    d[node] = 1; // the node itself
    int maxSubTree = 0; // subtree that has the most number of nodes
    for (int i = 0; i < tree[node].size(); i++) {
        int son = tree[node][i];
        if (son != parent) {
            dfs(son, node);
            d[node] += d[son];
            maxSubTree = max(maxSubTree, d[son]);
        }
    }
    maxSubTree = max(maxSubTree, N - d[node]); // "upside substree with (N - d[node]) nodes"

    if (maxSubTree < minBalance){
        minBalance = maxSubTree;
        minNode = node;
    }
}

int main()
{
    scanf("%d", &N);
    for (int i = 1; i <= N - 1; i++){
        tree[i].clear();
    }
    for (int i = 1; i <= N-1; i++){
        int u, v;
        scanf("%d%d", &u, &v);
        tree[u].push_back(v);
        tree[v].push_back(u);
    }
    minNode = 0;
    minBalance = INF;
    dfs(1, 0); // fist node as root
    printf("%d %d\n", minNode, minBalance);
    return 0;
}

G-送分了QAQ

题目描述
杭州人称傻乎乎的人为62,而嘟嘟家这里没有这样的习俗。
相比62,他那里的人更加讨厌数字38,当然啦,还有4这个
数字!所以啊,嘟嘟不点都不想见到包含38或者4的数字。
每次给出一个区间[n,m],你能找到所有令人讨厌的数字吗?
链接:https://www.nowcoder.com/acm/contest/74/G
题解
枚举。注意区间只有[0,1000000],预处理方式很好的解决时间复杂度问题。
代码

#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int main()
{
    int n,m;
    a[0]=0;
    for(int i=1;i<=1000000;i++){
        int t=i;
        a[i]=a[i-1];
        while(t)
        {
            if(t%10==4) break;
            if(t%100==38) break;
            t/=10;
        }
        if(t) a[i]++;
    }
    while(~scanf("%d%d",&m,&n)){
        if(n==0&&m==0) break;
        printf("%d\n",a[n]-a[m-1]);
    }
}

H-了断局

题目描述
既然是了断局了,大家就随便玩玩数字呗。
已知一个数列前10项分别是
{0, 1, 1, 2, 4, 7, 13, 24, 44, 81}
小G不满足呀:我要更多的数!!!不给就不让你们玩了。
小G会问你第n项是什么数字,请回答这个顽皮的孩子吧。
链接:https://www.nowcoder.com/acm/contest/74/H
题解
递归。F(n)=F(n-1)+f(n-2)+f(n-3),n>=4.
代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a[55];
LL f(int n)
{
    if(n==1) return a[n]=0;
    else if(n==2) return a[n]=1;
    else if(n==3) return a[n]=1;
    else{
        if(a[n]) return a[n];
        else return a[n]=f(n-1)+f(n-2)+f(n-3);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        printf("%lld\n",f(n));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值