续 洛谷:洛谷:数学思想开始了?还远远未到!(3)https://blog.csdn.net/Deeplow/article/details/104425501
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 校门外的树
【代码】
#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 小鱼的数字游戏
【代码】
#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
代表的是输入的数的个数(因为 j
与 count[j]
中的j
保持了统一(见下)
【循环体里 j++;
和count[j] = x;
的次序保证了统一(j
初始化为-1)!】
scanf("%d",&x);
j++;
count[j] = x;
那么后文: 因为要求输出的时候省略作为结束信号的0。而由上文发现,j
初始化为-1导致了此时的j
就是应该输出的数的个数(由count[j]
与j
的j
值统一可发现,在赋值的时候数组最后一项的下标是数组的容量减一)。
因此直接写出:
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 小鱼比可爱
【代码】
#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 珠心算测验
【代码】
#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 统计天数
【代码】
#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;
}
【分析】
……引用了库函数……我懒了