牛客练习赛9

珂朵莉的假动态仙人掌
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

珂朵莉想每天都给威廉送礼物,于是她准备了n个自己的本子

她想送最多的天数,使得每天至少送一个本子,但是相邻两天送的本子个数不能相同

珂朵莉最多送几天礼物呢

输入描述:

第一行一个整数n

输出描述:

第一行输出一个整数,表示答案
示例1

输入

4

输出

3

说明

第一天送1个本子
第二天送2个本子
第三天送1个本子

备注:

对于100%的数据,有1 <= n <= 1000000000

被动态仙人掌吓到了,但是肯定就是选1,2了,直接出答案

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n;
    cin>>n;
    long long num=n/3*2;
    if(n%3)num++;
    cout<<num;
    return 0;
}
珂朵莉的值域连续段
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续

一些数在值域上连续的意思即其在值域上构成一个连续的区间

输入描述:

第一行有一个整数n,表示树的节点数。
接下来n–1行,每行两个整数x,y,表示存在一条从x到y的有向边。
输入保证是一棵有根树。

输出描述:

输出一个数表示答案
示例1

输入

5
2 3
2 1
2 4
4 5

输出

5

说明

节点1子树中编号为1,值域连续
节点3子树中编号为3,值域连续
节点5子树中编号为5,值域连续
节点4子树中编号为4,5,值域连续
节点2子树中编号为1,2,3,4,5,值域连续

备注:

对于100%的数据,有n <=100000

两次dfsGG,还是带值的dfs比较稳,也可以线段树去维护最大最小值,现在看看完全没有必要

试着分析一下复杂度吧,我的进行了两边dfs,即使我按照从下向上的dfs了,看起来每次更新已经少了很多,但是难抵数据毒辣,而且更新的次数很多啊,就被卡了

从上往下dfs,利用dfs序的优点(访问下面的同时也对当前状态进行了更新),虽然多申请了变量,但是复杂度还是非常优秀的

#include<bits/stdc++.h>
using namespace std;
vector<int>G[100005];
int fa[100005];
int n,ans=0;
int find(int a)
{
    return fa[a]==a?a:find(fa[a]);
}
void dfs(int u,int &ma,int &mi,int &t)
{
    ma=mi=u,t=1;
    for(auto X:G[u])
    {
        int a,b,c;
        dfs(X,a,b,c);
        if(b-a+1==c)ans++;
        if(a<ma)ma=a;
        if(b>mi)mi=b;
        t+=c;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)fa[i]=i;
    for(int i=1,x,y; i<n; i++)
        scanf("%d%d",&x,&y),G[x].push_back(y),fa[y]=x;
    int a,b,c;
    dfs(find(1),a,b,c);
    if(b-a+1==c)ans++;
    printf("%d\n",ans);
    return 0;
}
 
最后这份代码我还是非常满意的,很nice
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
vector<int>G[N];
int fa[N],ma[N],mi[N],t[N],n,ans;
int find(int a)
{
    return fa[a]==a?a:find(fa[a]);
}
void dfs(int u)
{
    ma[u]=mi[u]=u,t[u]=1;
    for(auto X:G[u])
    {
        dfs(X);
        t[u]+=t[X],ma[u]=max(ma[u],ma[X]),mi[u]=min(mi[u],mi[X]);
    }
    if(ma[u]-mi[u]+1==t[u])++ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)fa[i]=i;
    for(int i=1,x,y; i<n; i++)
        scanf("%d%d",&x,&y),G[x].push_back(y),fa[y]=x;
    dfs(find(1));
    printf("%d\n",ans);
    return 0;
}

 

珂朵莉的假toptree
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

珂朵莉想求123456789101112131415...的第n项

输入描述:

第一行一个整数n

输出描述:

第一行输出一个整数,表示答案
示例1

输入

3

输出

3
示例2

输入

11

输出

0

说明

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4...
第3个是3
第11个是0

备注:

对于100%的数据,有1 <= n <= 1000

stringsteam很休闲的

#include<bits/stdc++.h>
using namespace std;
string c;
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<1005; i++)
    {
        stringstream ss;
        ss<<i;
        c+=ss.str();
    }
    printf("%c",c[n-1]);
    return 0;
}

 

 

posted @ 2017-12-30 12:55  暴力都不会的蒟蒻  阅读(419)  评论(0编辑  收藏  举报