牛客练习赛9

A 珂朵莉的假动态仙人掌.
题目描述
珂朵莉想每天都给威廉送礼物,于是她准备了n个自己的本子
她想送最多的天数,使得每天至少送一个本子,但是相邻两天送的本子个数不能相同
珂朵莉最多送几天礼物呢
输入描述:
第一行一个整数n
输出描述:
第一行输出一个整数,表示答案
示例1
输入
4
输出
3

说明
第一天送1个本子
第二天送2个本子
第三天送1个本子
备注:
对于100%的数据,有1 <= n <= 1000000000

分析:
一个序列:1 2 1 2 1 2 1 ······
n取值:1 2 3 4 5 6 7 8 9 ···· 简单找规律。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;

int main() {
    int n;
    scanf("%d", &n);
    int m1 = n % 3;
    int m2 = n / 3;
    printf("%d\n",m2 * 2 +  (m1 ? 1: 0));
    return 0;
}

B 珂朵莉的值域连续段.
题目描述
珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续
一些数在值域上连续的意思即其在值域上构成一个连续的区间
输入描述:
第一行有一个整数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

分析:
在每个节点处,记录其子树的最大值和最小值(左右区间),连续区间只需要满足 =maxmin+1子节点=max−min+1;
两遍DFS搜一下就行了

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;

const int maxn = 100010;
vector<int> v[maxn];
int in[maxn];

struct node {
    int ma;
    int mi;
}s[maxn];

node dfs(int x) {
    node p1;
    p1.ma = x;
    p1.mi = x;
    for(int i = 0; i < v[x].size(); i++) {
        int cnt = v[x][i];
        node p2 = dfs(cnt);
        p1.ma = max(p1.ma, p2.ma);
        p1.mi = min(p1.mi, p2.mi);
    }
    s[x] = p1;
    return p1;
}

int vis[maxn];

int DFS(int x) {
    int res = 1;
    int ans = s[x].ma - s[x].mi + 1;
    for(int i = 0; i < v[x].size(); i++) {
        int cnt = v[x][i];
        res += DFS(cnt);
    }
    if(res == ans) vis[x] = 1;
    else vis[x] = 0;
    return res;
}

int main() {
    int n, x, y;
    scanf("%d", &n);
    for(int i = 1; i < n; i++) {
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        in[y]++;
    }
    int root;
    for(int i = 1; i <= n; i++) {
        if(!in[i]) {
            root = i;
            break;
        }
    }
    dfs(root);
    DFS(root);
    int sum = 0;
    for(int i = 1; i <= n; i++) {
        if(vis[i]) sum++;
//      printf("#%d %d\n", s[i].ma, s[i].mi);
    }
    printf("%d\n", sum);
    return 0;
}

D 珂朵莉的假toptree
题目描述
珂朵莉想求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

分析:
简单模拟打个表就行.

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;

int dp[10010];

void init() {
    int p = 1;
    for(int i = 1; i <= 400; i++) {
        int ans = i;
        int res = 0;
        int cnt[10];
        while(ans) {
            cnt[res++] = ans % 10;
            ans /= 10;
        }
        for(int j = res - 1; j >= 0; j--) {
            dp[p++] = cnt[j];
        }
    }
}

int main() {
    init();
    int n;
    scanf("%d", &n);
    printf("%d\n", dp[n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值