NOIP2005 普及组题解

为获取最佳阅读效果,建议访问:Actinoi’s blog

T1:陶陶摘苹果

题目描述

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 10 10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 30 30 30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

现在已知 10 10 10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

输入输出格式

输入格式:

输入包括两行数据。第一行包含 10 10 10 100 100 100 200 200 200之间(包括 100 100 100 200 200 200)的整数(以厘米为单位)分别表示 10 10 10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个 100 100 100 120 120 120之间(包含 100 100 100 120 120 120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。

输出格式:

输出包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。

输入输出样例

输入样例#1:

100 200 150 140 129 134 167 198 200 111
110

输出样例#1:

5

说明

NOIP2005普及组第一题

题解:

本题直接模拟就可以。读入每个苹果的高度和陶陶的把手伸直的时候能够达到的最大高度,将最大高度加 30 30 30 ,便是陶陶站在板凳可以碰到的最大高度。然后再依次比较是否能够触碰到这个苹果就可以

#include 
using namespace std;
int apple[11];
int main() {
    int ans = 0, tall = 0; //存储陶陶能够摘到的苹果的数目以及陶陶把手伸直的时候能够达到的最大高度
    for (int i = 1; i <= 10; i++) //读入每个苹果的高度
        cin >> apple[i];
    cin >> tall;
    tall += 30; //陶陶能够达到的最大高度
    for (int i = 1; i <= 10; i++)
        if (apple[i] <= tall)
            ans++;
    cout << ans << endl;
    return 0;
}

T2:校门外的树

题目描述

某校大门外长度为 L L L的马路上有一排树,每两棵相邻的树之间的间隔都是 1 1 1米。我们可以把马路看成一个数轴,马路的一端在数轴 0 0 0的位置,另一端在 L L L的位置;数轴上的每个整数点,即 0 , 1 , 2 , … , L 0,1,2,…,L 0,1,2,,L都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入输出格式

输入格式:

第一行有 2 2 2个整数 L ( 1 ≤ L ≤ 10000 ) L(1≤L≤10000) L(1L10000) M ( 1 ≤ M ≤ 100 ) M(1≤M≤100) M(1M100) L L L代表马路的长度, M M M代表区域的数目, L L L M M M之间用一个空格隔开。
接下来的 M M M行每行包含 2 2 2个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出格式:

1 1 1个整数,表示马路上剩余的树的数目。

输入输出样例

输入样例#1:

500 3
150 300
100 200
470 471

输出样例#1:

298

说明

NOIP2005普及组第二题

对于 20 % 20\% 20%的数据,区域之间没有重合的部分;

对于其它的数据,区域之间有重合的情况。

题解:

利用模拟,设置一个 b o o l bool bool 类型的 r a i l w a y railway railway 数组,有地铁标记为 t r u e true true ,无地铁标记为 f a l s e false false

每读入一个区间,从这个起点开始,一直到终点都标记为 t r u e true true 。最后扫描一遍 r a i l w a y railway railway 数组,输出标记为 f a l s e false false 的总个数就可以。

#include 
using namespace std;
bool railway[10001]; //有地铁标记为true,无地铁标记为false
int main() {
    int l, m; //l代表马路的长度,m代表区域的数目
    cin >> l >> m;
    for (int i = 1; i <= m; i++) {
        int start, end; //存储一个区域的起始点和终止点的坐标
        cin >> start >> end;
        for (int j = start; j <= end; j++)
            railway[j] = true;
    }
    int ans = 0; //存储马路上标记为false的总个数
    for (int i = 0; i <= l; i++)
        if (railway[i] == false)
            ans++;
    cout << ans << endl;
    return 0;
}

T3:采药

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入输出格式

输入格式:

第一行有 2 2 2个整数 T ( 1 ≤ T ≤ 1000 ) T(1≤T≤1000) T(1T1000) M ( 1 ≤ M ≤ 100 ) M(1≤M≤100) M(1M100),用一个空格隔开, T T T代表总共能够用来采药的时间, M M M代表山洞里的草药的数目。
接下来的 M M M行每行包括两个在 1 1 1 100 100 100之间(包括 1 1 1 100 100 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式:

1 1 1个整数,表示在规定的时间内可以采到的草药的最大总价值。

输入输出样例

输入样例#1:

70 3
71 100
69 1
1 2

输出样例#1:

3

说明

对于 30 % 30\% 30%的数据, M ≤ 10 M≤10 M10

对于全部的数据, M ≤ 100 M≤100 M100

NOIP2005普及组第三题

题解:

一个背包 D P DP DP问题。我们读入采每株草药的时间和这株草药的价值,然后进行 D P DP DP

我们从第一株草药开始枚举 ( i ) (i) (i) ,以时间为单位进行倒序枚举 ( j ) (j) (j) 。若 j j j 减去采摘这株草药的时间 ≥ 0 ≥0 0 ,我们便可以在 j j j 时间内可以采到的草药的最大总价值: D P [ j ] = m a x ( D P [ j ] , ( D P [ j − 采 摘 这 株 草 药 的 时 间 ] + 采 取 这 株 草 药 的 价 值 ) ) DP[j] = max(DP[j], (DP[j - 采摘这株草药的时间] + 采取这株草药的价值)) DP[j]=max(DP[j],(DP[j]+))。最后我们输出 D P [ T ] DP[T] DP[T] 就可以了。

那么,为什么 j j j 要从 T T T 1 1 1 进行枚举呢?因为,每株草药只能被采一次,如果从 1 1 1 T T T 进行枚举的话,那么,一株草药可能被反复采许多次,所以,只能从 T T T 1 1 1 进行枚举。

#include 
using namespace std;
int herb[101][3]; //存储采摘某株草药的时间和这株草药的价值
int DP[1001];
int main() {
    int T, M; //T代表总共能够用来采药的时间,M代表山洞里的草药的数目
    cin >> T >> M;
    for (int i = 1; i <= M; i++)
        cin >> herb[i][1] >> herb[i][2];
    for (int i = 1; i <= M; i++)
        for (int j = T; j >= 1; j--)
            if ((j - herb[i][1]) >= 0)
                DP[j] = max(DP[j], (DP[j - herb[i][1]] + herb[i][2]));
    cout << DP[T] << endl;
    return 0;
}

T4:循环

题目描述

乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。

众所周知, 2 2 2的正整数次幂最后一位数总是不断的在重复 2 , 4 , 8 , 6 , 2 , 4 , 8 , 6 … 2,4,8,6,2,4,8,6… 2,4,8,6,2,4,8,6我们说 2 2 2的正整数次幂最后一位的循环长度是 4 4 4(实际上 4 4 4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:

    循环    循环长度
2   2,4,8,6   4
3   3,9,7,1   4
4   4,6       2
5   5         1
6   6         1
7   7,9,3,1   4
8   8,4,2,6   4
9   9,1       2

这时乐乐的问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数 n n n的正整数次幂来说,它的后 k k k位是否会发生循环?如果循环的话,循环长度是多少呢?

注意:

1. 如果 n n n的某个正整数次幂的位数不足 k k k,那么不足的高位看做是 0 0 0

2. 如果循环长度是 L L L,那么说明对于任意的正整数 a , n a,n a,n a a a次幂和 a + L a+L a+L次幂的最后 k k k位都相同。

输入输出格式

输入格式:

一行,包含 2 2 2个整数 n ( 1 ≤ n < 1 0 100 ) n(1≤n<10^{100}) n(1n<10100) k ( 1 ≤ k ≤ 100 ) k(1≤k≤100) k(1k100) n n n k k k之间用一个空格隔开,表示要求 n n n的正整数次幂的最后 k k k位的循环长度。

输出格式:

一个整数,表示循环长度。如果循环不存在,输出 − 1 −1 1

输入输出样例

输入样例#1:

32 2

输出样例#1:

4

说明

对于 30 % 30\% 30%的数据, k ≤ 4 k≤4 k4

对于全部的数据, k ≤ 100 k≤100 k100

NOIP2005普及组第四题

题解:

占坑待填。。。

你可能感兴趣的:(NOIP2005 普及组题解)