洛谷:数组的引入(4)

续 洛谷:洛谷:数学思想开始了?还远远未到!(3)https://blog.csdn.net/Deeplow/article/details/104425501

P1046 陶陶摘苹果

P1046 陶陶摘苹果
【代码】

#include <stdio.h>
int main ()
{
	int a[10];
	int length;
	int i;
	for ( i=0; i<10; i++){
		scanf("%d",&length);
		a[i]= length;
	}
	int ability;
	int count =0;
	scanf("%d",&ability);
	for ( i=0; i<10; i++){
		if ( a[i] <= ability +30)
		count++;
	}
	printf("%d",count);
	return 0;
}

【分析】
1、用for循环、数组记录数据;
2、用for循环在特定条件(if语句)下使得计数器(count)增加。

P1047 校门外的树

P1047 校门外的树
【代码】

#include <stdio.h>
int main ()
{
	int length;
	int rest=0;
	scanf("%d",&length);
	length = length + 1;
	int area_number;
	scanf("%d",&area_number);
	int l[length];
	int i;
	for ( i=0; i<length; i++){
		l[i] = 1;
	}
	int start,over;
	int k;
	for ( k=0; k<area_number; k++){
		scanf("%d%d",&start,&over);
		
		for ( i=0; i<length; i++){
			
			if (i >= start && i <= over){
				l[i]=0;
			}
		}
	}

	for ( i=0; i<length; i++){
		if ( l[i]==1){
			rest++;
		}
	}

	printf("%d",rest);
	return 0;	
}

【分析】首先对题目进行简单的分析和转换:

1、思路

题目中提到马路和数轴的概念,其实可以转换成数轴和数轴上的整数点的概念。

2、转化

那么题目就可以看成:
背景:一个数轴,从零开始,一直到L,一共记录有L+1个点(包括两端);
操作:设置若干个范围,每一次都将该范围上的点(闭区间)抹除;
问题:剩余多少个点?

3、代码实现

那么如何解决呢?
①代码的常规操作(正常的输入、数组的定义和初始化);
ps:在此特别注意不要把数组的长度定义错了,见背景。
②首先利用数组把讨论范围内的数组中的数都定义为1(相当于元素全为1的容器),此时1的含义就是“”;
然后就是想办法把应该需要移走的树(也就是数轴上的点)设置为0,此时0的含义就是“”;
③对于设置0的方法,这一用了一个嵌套的for循环
外层设置for循环的原因是因为都多个区域需要设置,不同区域之间无规律可循。因此只需将for循环的长度设置为区域的个数;
内层for循环的目的就是区域内部的处理,将数组中大于等于起点的,小于等于终点的数都设置为0(注意首尾都是0)。
④最后一开始所设置的计数数组就被我们转换成了“答案数组”,只需利用for循环遍历数组,用计数器显示1的个数就可以了。最后输出。

P1427 小鱼的数字游戏

P1427 小鱼的数字游戏
【代码】

#include <stdio.h>
int main ()
{
	int x=0;
	int i=0;
	int count[100];
	for ( i=0; i<100; i++){
		count[i]=0;
	}
	int j=-1;
	do
	{
		scanf("%d",&x);
	    j++;
		count[j] = x;
	    
	}while ( x!= 0);
	int k=0;
	int count_out[j];
	for ( k=0; k<j; k++){
		count_out[j-k-1]=count[k];
	}
	for ( k=0; k<j; k++){
	   	printf("%d ",count_out[k]);
	}
	return 0;
}

【分析】我们先来分析一下这个代码的流程。
题目看似非常简单(对大佬来讲就是非常简单),对于我这种真正的蒟蒻,只能一步一步的来。

1、思路

设置两个数组,一个用来输入,一个人用来输出。

2、转化

题目就是:输入一行数,倒序输出,然后省去作为结束信号的0.

3、代码实现

正常操作:(变量的定义和初始化,数组的定义和初始化);
ps:对于未知个数的变量录入数组,将数组过的容量设置为足够大即可;但是在输入这些变量的时候一般都有结束信号(如本题的0),才可用while循环终止录入数据。

注意事项:
在定义第一个数组时,以及把数据录入到第二个数组时,要有清晰的头脑明白其中的连接关系,不然因为少加或多加一导致录入错位,或者是数据缺失和凭空出现,都是十分滑稽的行为。
下面清清楚楚地表达一下关系(没错学渣就是要这么做):

数组的使用规范

1. 条分缕析
为了使用数组的规范化,方便以后操作,一律采用从0开始计数;
这样做有几点好处和规律:
①定义数组时,方括号里面是多少,就能放多少个数(容量);
②一律采用下面的格式,如果有微调,在“整数”一处发挥即可。

int i;
for ( i=0; i<整数; i++){语句}

例如

int count[100];
	for ( i=0; i<100; i++){
		count[i]=0;
	}

2. 根据代码和题目说事

前文:j代表的是输入的数的个数(因为 jcount[j]中的j保持了统一(见下)
【循环体里 j++;count[j] = x;的次序保证了统一(j初始化为-1)!】

scanf("%d",&x);
    j++;
	count[j] = x;

那么后文: 因为要求输出的时候省略作为结束信号的0。而由上文发现,j初始化为-1导致了此时的j就是应该输出的数的个数(由count[j]jj值统一可发现,在赋值的时候数组最后一项的下标是数组的容量减一)。
因此直接写出:

int k=0;
	int count_out[j];
	for ( k=0; k<j; k++){
		count_out[j-k-1]=count[k];
	}

3、倒序对应的烦人事

有没有发现上面的片段出现了:

count_out[j-k-1]=count[k];

为啥要减一?
本来j代表的就是输出的数的个数,k都是从0开始计数的(规范的好处),根据数组最后一项数组的下标是数组的容量减一,所以需要减一(末项对应首项,所谓倒序对应),然后自然就把末尾的零略去了。
对齐了一项,又规定了起点,肯定了数组的容量,结果必然是规范的。
4、开心的输出

for ( k=0; k<j; k++){
	   	printf("%d ",count_out[k]);
	}

回头一看只要输出就OK了哈哈哈!

ps:此处设置do-while循环是因为x初始化的值就是0,进行一次输入就可以避免跳出循环。使用do-while循环就是为了避免初始化导致直接跳出循环!(见下)

do
{
	scanf("%d",&x);
    j++;
	count[j] = x;
    
}while ( x!= 0);

下面提供一个其他人写的关于数组的知识,标上出处(瞻仰大佬)。

[数组用法小技巧版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。]
(https://blog.csdn.net/u011017694/article/details/84763815)

【零分的代码】
只要一个加一或者减一不规范,就会导致输出的全面崩盘
一方面我们要努力探索其中的逻辑关系,但是更重要的是,我们要遵守写代码(定义数组)的规范
这样会使我们更流畅的写出代码,并且把问题的聚焦点放在有价值的地方,避免无谓的转圈圈。

P1428 小鱼比可爱

P1428 小鱼比可爱
【代码】

#include <stdio.h>
int main ()
{
	int number;
	scanf("%d",&number);
	int cute[number];
	int c_number;
	int i;
	for ( i=0; i<number; i++){
		scanf ("%d",&c_number);
		cute[i]=c_number;
	}
	int comp[number];
	for ( i=0; i<number; i++ ){
		comp[i]=0;
	}

	for ( i=1; i<number; i++ ){
		int j;
		for ( j=0; j<i; j++ ){
			if ( cute[i]>cute[j] ){
				comp[i] = comp[i] +1;
			}
		}
	}
	for ( i=0; i<number; i++ ){
		printf ("%d ",comp[i]);
	}
	return 0;
}

【分析】
1、日常操作;
2、嵌套的for循环:外层的for循环用来确保每一个小鱼参与计算;内层的for循环确保每一个排在该小鱼的左边的小鱼得到比较;
3、用计数器记录即可。

P2141 珠心算测验

P2141 珠心算测验
【代码】

#include <stdio.h>
int main()
{
    int n,c,d,e=0;
    scanf("%d",&n);
    int a[n],b[n];
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]); 
        b[i]=a[i];
    }
    for(int i=1;i<=n-1;++i)
    {
        c=a[i];  
        for(int j=i+1;j<=n;j++)
        {
            d=a[j];   
            for(int k=1;k<=n;k++)
            {
                if( b[k] == c+d)  
                {
                    e++;  
                    b[k] = 0;  
                }
            } 
        }
    }
    printf("%d",e);
	return 0;  
}

【分析】关键就是避免类似于5=1+4;5=2+3的重复。

P1567 统计天数

P1567 统计天数
【代码】

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i,n,x,max=0,z=0,y=0;
    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if (y<x) {z++;y=x;}
        else
            if (max<z) {max=z;y=x;z=1;}
            else {
                y=x;
                z=1;
            }
    }
    if (max==0) {
           printf("%d\n",n); 	
    }
    else  {
    printf("%d\n",max);
}
    return 0;
}

【分析】
……引用了库函数……我懒了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值