一维数组 下标的应用

概念:

①初始化的数组,其下标是从0开始计数!

②数组的下标是 int 类型,下标具有唯一性!

第1题  小鸟(程序填空)【L1】

有n只小鸟,依次读入n只小鸟的类型,小鸟类型的是一个正整数。有m次询问,每次询问给出一个a,表示询问有多少只小鸟的类型是a。

输入格式

第一行,一个整数n。1<=n<=100000。

第二行,n个正整数,第i个整数表示第i只小鸟的类型,范围是[1,1000000]。

第三行,一个询问次数m。1<=m<=100000。

第四行,m个正整数,第i个整数a表示询问类型是a的小鸟的数量。

输出格式

一行,共m个整数,每个整数对应一个询问的答案,空格分开。

输入/输出例子1

输入:

5

2 10 8 9 2

3

8 11 2

输出:

1 0 2

1-19.png

样例解释

方法一:

把n个整数读入保存到数组。

对于每一个询问,用一个for循环扫描数组,统计x出现的次数。有m次询问,每次询问扫描一遍数组需要扫描n个元素,所以时间复杂度是O(n*m)=10^5 * 10^5 = 10^10,约需要10秒,超时。

方法二:

可以假设有1000000只鸟笼,编号是1至1000000,一开始所有笼子都没有小鸟,然后有n只小鸟排队依次飞进鸟笼,类型x的小鸟会飞进编号是x的鸟笼。然后对于每一个询问a,只需要回答编号是a的鸟笼有多少只小鸟即可。可以用数组box[10000005]来表示1000000只鸟笼,用box[i]记录编号是i的鸟笼目前有多少只小鸟。然后用for循环读入每只小鸟的类型,模拟小鸟飞进鸟笼的过程,假设第i只小鸟的类型是x,那么它会飞进编号是x的鸟笼,该鸟笼的小鸟数量加1,也就是box[x]++即可。当所有小鸟都飞进鸟笼之后,对于每一个询问,输出相应的鸟笼里面小鸟数量即可,例如询问类型是a的小鸟的数量,只需要输出box[a]即可。

练习一

第1题分糖果(程序填空)【L2】

有n个小朋友,学号从1至n。圣诞节会有m次分糖互动,第i次活动给学号是a至b的小朋友分1颗糖果。问哪个小朋友得到的糖果数量最多?

输入格式

第一行,两个整数n和m。1<=n,m<=5000。

接下来有m行,每行两个整数a和b。1<=a<=b<=n。

输出格式

一个整数,表示得到最多糖果的那个学生的学号,如果有多位学生得到的糖果都是最多的,那么输出他们当中学号最大的。

输入/输出例子1

输入:

10 2

3 5

4 10

输出:

5

1-20.png

例题二

第1题数组计数排序(程序填空)【L9】

有n(n<=10000)件物品,依次读入这n件物品的重量,每件物品重量都不超过10000的整数,现在你要按照从轻到重的次序,输出这n件物品的重量。

分析问题

第一步,开一个数组c[10005],其中c[i]保存的是有多少件重量是i的物品,初始化c数组为0,表示暂时没有任何物品。

第二步,用循环读入n件物品的重量,设第i件物品重量是x,那么就让c[x]++,表示重量是x的物品增加了一件。

第三步,用循环从1枚举到10000,当枚举到i时,因为c[i]保存的是有多少件物品的重量是i,所以我们用循环输出c[i]个i。

这样就完成了从小到大排序的目标。

下面给出一个样例,假如输入的是:

7

3 6 7 3 7 8 3

输入格式

第一行,一个整数n。

第二行,n个正整数。

输出格式

从小到大排序后输出

输入/输出例子1

输入:

7

3 6 7 3 7 8 3

输出:

3 3 3 6 7 7 8

1-21.png

深入理解以下例子代码!先写下自己的方法,再去验证和对比参考代码。

例1:输入n个整数,存放在数组a[1]至a[n]中,输出最大数所在位置(n<=10000)。

输入样例:

5

67 43 90 78 32

输出样例:3

分析:设maxa存放最大值,k存放对应最大值所在的数组位置,maxa的初值为a[1],k的初值对应为1,枚举数组元素,找到比当前maxa大的数成为maxa的新值,k值为对应位置,输出最后的k值。

1-22.png

例2:有n个人,编号为1~n。开始时,所有人都站着,接着第2个人及2的倍数的人坐下,然后,第3个人及3的倍数的人按相反的操作(站的人坐下,坐的人站起来),依此类推,一共操作到第k人及k的倍数,问最后哪些人站着?输入n和k,输出站着人的编号(k≤n≤10000)。

输入样例:7     3

输出样例:1 5 6 7

分析:用a[1]、a[2]、…、a[n]表示编号为1、2、3、…、n的人是否站着,初值都为0,表示都站着,让i从2到k循环,将a数组中i倍数的元素值取反。输出a数组中值为0的元素。

1-23.png

例3:学校推出了10名歌手,校学生会想知道这10名歌手受欢迎的程度,设了一个投票箱,让每一个同学给自己喜欢的歌手投票,为了方便,学生会把10个歌手用1-10进行编号,这样,同学们只要用编号进行投票了。

现在,学生会找到你,帮助统计一下每个歌手获得的票数。

分析:

很直观的想法是,投谁,谁的票数加1。如:投2号,则2号的票数加1,投6号,6号的票数加1。如何表示这么一个操作过程呢?

设变量num[i]表示第i个歌手的票数,相当于用名称num表示票数,然后再对名称进行编号,编号为i的num表示第i个歌手的票数。这样,投2号,则2号的票数加1,就可以表达为:i=2;num[i] = num[i]+1投6号,则6号的票数加1,就可以表达为:i=6;num[i] = num[i]+1

归纳上述分析,具体实现步骤如下:

(1)开辟num[1]~num[10]变量分别存放10个歌手的票数。

(2)读入选票赋给i。

(3)对应选票i的歌手票数加1,即num[i]=num[i]+1。

(4)重复(2)和(3)的操作,直到读完选票为止。

(5)输出每位歌手的票数。

1-24.png

例4:输入n个数,存入数组a中,每一个数都是介于0到k之间的整数,此处k为某个整数(n≤100000,k≤1000),按从小到大的顺序输出a数组中的数据。

分析:看了问题,我们直观的想法是将a数组中的数据实现从小到大的顺序排序。排序的方法有多种,效率也不一样。但本问题有一个重要的特点就是每一个数都是介于0到k之间的整数,而且k的值很小,我们可以开设一个下标为0~k的数组c,c[0]记录a数组中值为0的个数,c[1]记录a数组中值为1的个数,……,c[k]记录a数组中值为k的个数,那么按从小到大的顺序输出个数为c数组元素值的c数组下标值,即按从小到大的顺序输出a数组中的数据。

实现步骤如下:

(1)读入数据存放在a数组中,设数组c,c[x]存放值为x的个数。

(2)对于a数组中的n个数,统计值为ai]的个数,c[ a[i] ] - c[ a[i] ]+1。

(3)循环i:0~k,输出c[i]个i。

1-25.png

例5:给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0~9的拼法如图5.1所示。输入整数n(n<=24),输出能拼成的不同等式的数目。

1-26.png

注意:

(1)加号与等号各自需要两根火柴棍。

(2)如果A!=B,则A+B=C与B+A=C视为不同的等式(A、B、C>=0)。

(3)n根火柴棍必须全部用上。

输入样例:18

输出样例:9

输出样例解释:

0+4=4

0+11=11

1+10=11

2+2=4

2+7=9

4+0=4

7+2=9

10+1=11

11+0=11

分析:设等式中的三个变量为A、B、C,如果已知A和B,则C=A+B。

由于题目给出的火柴数目范围很小,可以穷举A、B值,求得C值,求出构成等式A+B=C的火柴数目,如果火柴数目为输入值,则为问题的一个解,累计解的个数即为本问题的最终答案。

对于本题,我们能否从细节上提高穷举的效率呢?

(1)根据n<=24条件,确定穷举A和B的范围。即如果都使用最少火柴的数字(如数字1)构造表达式中的数,得到最大的数是多少,可以算出该数<1000,因此A和B的范围为0~1000。

(2)在穷举表达式过程中,需要反复计算每个数所用的火柴数目,即相同的数有可能重复计算许多次的火柴数目,显然,需要想办法减少重复计算。先进行预处理,将估算范围内的数所用的火柴数目算出。

(3)穷举过程中如果当前数的火柴数目超过输入限制做剪枝处理。

归纳上述分析,具体实现步骤如下:

(1)预处理:求0~2000数对应的火柴数目。

(2)使用循环枚举A值0~1000,执行下列操作:

①判断A值的火柴数目是否超过限制值,是的,剪枝,跳过该数的处理。

②否,使用循环穷举B值0~1000,执行下列操作:

·判断A和B值的火柴数目和是否超过限制值,是的,剪枝,跳过该数的处理。

·否,求C值,若A、B、C值火柴数目和等于限制值,计数方案数。

(3)输出方案数。

1-27.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值