数组语法以及数组例题精讲
数组语法
在我们编写某些程序的时候,我们有时候会用到大量的变量,如果此时我们去一个一个的定义我们所需要的变量,那么我们的效率无疑是十分低下的
所以,我们在这里学习数组以提升我们的效率
就跟上面所说的一样,数组简单来说就是一次定义很多个变量,语法如下:
定义的数组类型 数组名[数组数量]
具体的例子如下:
int a[100];
这样我们就定义了一个\(int\)类型的数组,数组大小是100
换句话说就是定义了100个\(int\)类型的变量
那么数组该如何使用呢?
就如上文所说,数组相当于定义了很多变量
如上面这个代码就相当于定义了\(a[0]\)到\(a[99]\),总共一百个变量
调用也跟变量差不多,举例如下:
int a[100];
for(int i=1;i<=10;i++)
{
cin>>a[i];
}
上述代码中,我们定义了大小为100的a数组,并输入了\(a[1]\)到\(a[10]\)十个值
如果我们需要将他们倒着输出,我们可以这样:
for(int i=10;i>0;i--)
{
cout<<a[i];
}
因为我们是从\(a[10]\)输出到\(a[1]\),所以就实现了倒着输出
数组的操作几乎同变量一样,是非常简单的,下面我们用一些例题来熟悉数组的操作
P1428 小鱼比可爱
本题的题意较为清晰,就是看每个数字前面有几个比自己小的,我们只需要枚举每一个前面的数字一次判断有几个比自己小的就行了
然后注意到\(n \leq 100\),所以我们只需要定义一个大小为100的数组就行了,但是出于本人的习惯,一般从a[1]开始使用,所以要定义多几个
因为定义的时候是从a[0]开始的,100个最大只有a[99]而不是a[100]
具体实现如下:
#include<iostream>
using namespace std;
int a[105];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
int ans=0;//表示答案,即有几个比自己小
for(int j=1;j<i;j++)//枚举从1开始到自己前一个,即所有在自己前面的数
{
if(a[j]<a[i])//如果比当前数小,答案加一
{
ans++;
}
}
cout<<ans<<" ";
}
return 0;
}
P5727 【深基5.例3】冰雹猜想
本题的循环操作显然是可以用while实现的,当x不等于1的时候就进行操作,等于的时候停止
问题是题目要求的输出是倒序,所以我们就用数组把变化过程先存下来,然后倒着输出就行了
具体实现如下:
#include<iostream>
using namespace std;
int a[100005];
int main()
{
int cnt=0;//代表现在一共存了几个数字
int x;
cin>>x;
cnt++;
a[cnt]=x;//刚开始是第一个数
while(x!=1)
{
if(x%2)//如果是奇数
{
x=x*3+1;
}
else//如果是偶数
{
x=x/2;
}
cnt++;
a[cnt]=x;//记录当前数
}
for(int i=cnt;i>0;i--)//倒序,所以从最后一个开始输出
{
cout<<a[i]<<" ";
}
return 0;
}
P1047 [NOIP 2005 普及组] 校门外的树
这道题我们看到从0开始就貌似天然适合数组,因为数组的下标也是从0开始计算的
本题的思路也比较简单,我们定义全局数组,这样数组的默认值就会是0
我们把a[i]等于0看成第i个位置有树,等于1看成第i个位置没有树
所以每次给一个区间我们只需要把对应的a数组赋成1,最后结束了统计还有几个0就行了
具体实现如下:
#include<iostream>
using namespace std;
const int MAXN=1e4+10;//科学计数法,xey代表x乘10的y次方
int a[MAXN];//定义全局数组,因为全局变量默认为0
int main()
{
int len,m;
cin>>len>>m;
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
for(int j=l;j<=r;j++)//除掉区间内所有树
{
a[j]=1;
}
}
int ans=0;//答案,即还剩几棵树
for(int i=0;i<=len;i++)//枚举每一个位置
{
if(a[i]==0)//这个位置还有树
{
ans++;
}
}
cout<<ans;
return 0;
}
P1614 爱与愁的心痛
本题要求所有连续m个数的和的最小值,所以我们用一个变量表示当前数往前m个长度的数的和
那么我们刚开始加上前m个数,然后从第m个开始枚举
每次都是减去第i-m个数,然后加上当前数,就是新的连续m个数的总和了
所以我们再用一个变量存下最小值,每次遇到更小值更新即可
具体实现如下:
#include<iostream>
using namespace std;
const int MAXN=3e3+10;//n最大为3x10的三次方,所以开那么大的数组就够了
int a[MAXN];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int sum=0;//记录连续m个数字的和
for(int i=1;i<=m;i++)//刚开始是前m个的和
{
sum+=a[i];
}
int ans=sum;//记录最大的和
for(int i=m+1;i<=n;i++)//开始枚举结尾数
{
sum-=a[i-m];//减去最前面的数
sum+=a[i];//加上当前数,这样就还是m个数字的和
ans=min(ans,sum);//更新最大值
}
cout<<ans;
return 0;
}
P5732 【深基5.习7】杨辉三角
本题需要用到杨辉三角的性质,其实就是每一行的当前项的值等于上一行的当前项和前一项之和
所以我们这题需要学会二维数组
简单来说就是数组中的每一项都是数组,例如
int a[100][100];
就是二维数组,其中每个a[i]就是一个长度为100的数组
同理,我们可以通过这种方式定义三维,四维或更高维的数组
这里不再赘述
回到本题,我们只需要定义一个二维数组,根据杨辉三角的性质,其实就可以写成:
a[i][j]=a[i-1][j]+a[i-1][j-1];
即每一行当前列的值等于上一行的当前列,加上上一行的前一列的值
所以,本题的具体实现如下:
#include<iostream>
using namespace std;
int a[25][25];
int main()
{
a[1][1]=1;//第一行只有一个1
int n;
cin>>n;
for(int i=2;i<=n;i++)//从第二行开始算值
{
for(int j=1;j<=i;j++)
{
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}

浙公网安备 33010602011771号