数组入门,洛谷题单C++

#一个日常总结做题的博客文章。博主用的Dve-C++#

先简单了解一下数组

数组可以想象成一串小房间用来放同一种类型的数据,比如整型,字符型等等。

定义一维数组,输入遍历输出 

如果你想输入东西放进数组可以循环输入要不然就要一个一个赋值

新手最容易犯的错误

1、主函数里没有赋值

2、下标混乱

3、数组越界(例题体现)

 

下面是输入方法

一、逐个赋值

#include <iostream>
using namespace std;
/*    下面是例子:这里需要注意数组是从0开始算a[0],a[1],a[2],a[3],a[4]一共5个整数
      []里为索引或者说下标就是房号啦,里面的数字表示元素的个数。*/

int a[5];           //这里定义默认都是0,={0,0,0,0,0} 没有a[5]!!!只有01234号房


int main()
{
    int b[5]={0};        //在主函数里面就需要={0},需要赋初始值,要不然会出现奇奇怪怪的东西。
    int bb[5]={1,2}      //其实就是={1,2,0,0,0}
                         //当然你还可以像变量一样赋值:
    bb[2]=3;             //结和起来是不是就是从0号房间开始数,2号房住了3。
    for(int i=0;i<5;i++) /*遍历一维数组需要一个循环,你想想房号是不是连续+1,这里不能=5,因为没
                            有5号房,而且你设置的是从0开始,开门看看住了谁*/
    {
        cout<<bb[i];     //输出的就是12300,1在0号房,2在1号房,3在2号房。。。
    }
    return 0;   
}

下面是一个错误代码: 

#include <iostream>
using namespace std;
int main()
{
	int bb[5];
	for(int i=0;i<5;i++)
	{
		cout<<bb[i];
	}
	return 0;
 } 

这个代码就是在主函数没有赋值是不是bb[2],bb[3]变成3,8了,我们要这样写就必须放外面如那个,a[5]那样,要不然就会出现像3,8这样莫名其妙的数字。

我来写一个输入代码

二、循环输入输出

#include <iostream>
using namespace std;
int bb[5];
int main()
{
	for(int i=0;i<5;i++)
	{
		cin>>bb[i];
	}
	for(int i=0;i<5;i++)
	{
		cout<<bb[i];
	}
	return 0;
 } 

 倒着输出:

 易错点:下标从4开始倒着输出不是从5开始。

除非输入就是从1开始,简单的理解就是你把一个队(5人)的第一个人放在哪里,放在1那整个队就是从1开始,顺序结束就也要从1开始,倒序就从5开始,始终要有那么多个人,不能少一个也不能乱找一个,他们住的房间是固定的不能找错房间。

是不是很简单,看到这里那么你已经掌握了基本输入输出和定义一维数组,那么我们来进入二维数组!

二维数组

二维数组和一维数组就像面和线的关系,如果说把一维看成一条x轴,那么二维就是有x轴,y轴的一个面,里面的每个点都需要用xy表示,那么怎样用代码实现呢?

一维用一个循环解决,那么二维就需要用两个了,下面我来写一个二维的代码

小重点: 

                1、外循环为行,内循环为列

                2、输入起始下标多少,要完整输出,则输出循环也要为那个起始下标。

                3、输出矩形记得换行。

定义二维数组 

可以在主函数外写默认都是零

#include <iostream>
using namespace std;
//默认是行2,列3都是0的矩阵 
int b[2][3];
//000 000

int main()
{
	int a[][3]={1,2,3,4,5,6};
	for(int i=0;i<2;i++)
	{
		//从0开始不能等于2,要不然就多了一行 
		for(int j=0;j<3;j++)
		{
			cout<<b[i][j];
			//从0开始 就不能等于3,要不然就多了一列 下面是输出 
			//000
			//000
			
		}
		cout<<endl;
	}
	return 0;
}

Dev-c++可以省略第一个[]但是,[][这个必须要写]  

#include <iostream>
using namespace std;
//默认是行2,列3都是0的矩阵 
int b[2][3];
//000 000

int main()
{
	int a[][3]={1,2,3,4,5,6};
	for(int i=0;i<2;i++)
	{
		//从0开始不能等于2,要不然就多了一行 
		for(int j=0;j<3;j++)
		{
			//从0开始 就不能等于3,要不然就多了一列 下面是输出
			cout<<a[i][j];
			//123
			//456
		}
		cout<<endl;
	}
	return 0;
}
 

 当然还有其他赋值方式大家自己多多尝试,二维和一维有很多相似点。

宝宝级解说: 

#include <iostream>
using namespace std;
//默认为5行5列,5*5=25个整数都为0。
int a[5][5]; 
//这里我们不做任何操作就输入输出 
int main()
{
	//如果我们从下标1开始,那么就可以=5结束,
	//因为你想输入5个整数 1~5还是5个,这次我们从1号房开始数
	//一个小重点:外循环相当于行,内循环相当于列,形成一个矩形 
	for(int i=1;i<=5;i++)
	{
		//i=1,j就要+1,5次,这个相当于一个a[1][j]一个矩形的第一行 
		for(int j=1;j<=5;j++)
		{
			cin>>a[i][j];
		} 
	}
	//如果输入是从1开始,那么你想完整输出就也要从1开始 
	//和一维一样输出遍历数组,不过是两层循环,
	//你就想,循环输出一行一维数组,是不是就输出了很多行,
	//输出了很多一维数组,这就相当于一个二维 
	for(int i=1;i<=5;i++)
	{
		for(int j=1;j<=5;j++)
		{
			cout<<a[i][j];
		} 
		//这个换行每循环一行就换,一行有5个内循环,五列
		cout<<endl; 
	}
	return 0;
}

我们来看看矩形效果和数组元素个数

可以看到我们输出了一个5行5列的矩形,个数为25即5*5,而且后面多输入的数字都被抛弃了。因为他们没有房间住,数据没有内存放,就丢弃了。

那么如何把数组玩花?其实只要你循环用的熟练会用下标做坐标🆗了!后续我会出一个循环系列

数组的使用

下面我写几段代码,来自洛谷数组入门题单

1,蛇形方阵

如果你没有接触过这种典型的题不妨试码一下,下面有我的思路和代码分享,当然欢迎评论区提问和提出更好的代码,洛谷有更加丰富的题解。

思路就是碰壁,递增方向都写一个循环,分享一下我的代码:

#include <iostream>
using namespace std;
int a[10][10];
int main()
{
	int n,b = 1;
	cin>>n;
	int x = 1, y = 0;
	while(b<= n*n)
	{
		while(y+1<=n&&!a[x][y+1]) a[x][++ y]=b ++;
		while(x+1<=n&&!a[x+1][y]) a[++ x][y]=b ++;
		while(y-1>=1&&!a[x][y-1]) a[x][-- y]=b ++;
		while(x-1>=1&&!a[x-1][y]) a[-- x][y]=b ++;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			printf("%3d",a[i][j]);
		}
		cout << endl;
	}
	return 0;
}
 

其实这里尤其要注意一点就是内层while循环判断的是下一个是不是0,有没有越界

2、杨辉三角

 思路:头尾为1,其他的等于他上面两个数的和,通过坐标实现。

代码:

#include <iostream>
using namespace std;
int a[21][21];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			if(j==1||i==j) a[i][j]=1;
			else  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<<endl;
	}
	return 0;
}

 3、用标记法解题

 

 思路:要么开要么关,我们就把开的按钮赋值+1标记,开一次就+1一次,没有开的按钮就为0,

只要取相乘的整数开编号就好,编号作为数组的下标(索引)+1.遍历整个数组循环赋值后,遍历

输出唯一一个%2>0,因为他们都有赋值+1,只有是偶数的也就是开了2*n次,和0次的是关,

开了奇数次为开编号,所以最后判断一下是不是这个数组的元素哪个是奇数,然后输出下标就好了。

下面是代码:

#include <iostream>
using namespace std;
int b[2000000];
int main()
{
	int n,t,c;
	double a;
	
	cin>>n;
	
	for(int i=1;i<=n;i++)
	{
		cin>>a>>t;
		for(int j=1;j<=t;j++)
		{
			c=(int)(a*j);
			b[c]++;
		}
	}
	for(int i=1;i<=2000000;i++)
	{
		if(b[i]%2>0)
		cout<<i;
	}
	return 0;
}

下面来一个二维的标记:

 思路:

这个代码是一样的方法也是亮就赋值为1,我们只需要确定火把和萤石位置,把他们周边方格=1,

这里我是特殊处理了火把的四个突出亮方格。其他的以一个矩形赋值,用坐标关系实现。

要注意一个越界问题一个n*n的范围,他们位置存不存在周边方格,存在才能赋值。还是需要一个

判断条件。输出不亮的个数需要遍历,不等于1,计数。

代码:

#include <iostream>
using namespace std;
int a[105][105];
int cut=0;
int main()
{
	int n,m,k,x,y;
	cin>>n>>m>>k;
	for(int ii=1;ii<=m;ii++)
	{
		cin>>x>>y;
		for(int i=x-1;i<=x+1;i++)
		{
			for(int j=y-1;j<=y+1;j++)
			{
				if(i>=1&&j>=1)
				a[i][j]=1;
			}
		}
		if(x-2>=1&&x+2<=n)  a[x-2][y]=1;
		if(x+2<=n&&x-2>=1)	a[x+2][y]=1;
		if(y-2>=1&&y-2<=n)	a[x][y-2]=1;
		if(y+2<=n&&y+2>=1)	a[x][y+2]=1;
		
	}
	for(int ii=1;ii<=k;ii++)
	{
		cin>>x>>y;
		
		for (int i=x-2;i<=x+2;i++)
		{
			for(int j=y-2;j<=y+2;j++)
			{
				if (i >= 1 && j >= 1)
				a[i][j]=1;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i][j]!=1) cut++;
		}
	}
	cout<<cut;
	return 0;
}

下面来写一道压缩技术的题

思路:先输入第一个数,确定一下行列,然后逐个输入后面的数字,记录输入了几个,判断奇偶个数,奇数个的就是0的个数,偶数个就是1的个数个的就是1的个数。要注意不能超出行列,所以记录一下输出到这列的第几个如果已经等于行数了那么下面我们就要输出换行并且计数要清零,循环利用

下面是代码:

#include <iostream>
using namespace std;

int main()
{
	int n,m,a=0,sum=0;
	cin>>n;
    //如果你不知道输入多少个那么我们可以用这种方法EOF就是-1,
    //结束输出要按Ctrl+z然后回车
	while((scanf("%d",&m))!=EOF)
	{
		a++;            //记录输入几个
		
		if(a%2!=0)    //奇数就循环m个0
		{
			for(int i=1;i<=m;i++)
			{
				cout<<"0";
				sum++;        //记录输出个数,不能超过n行n列
				if(sum==n)
				{
					cout<<endl;
					sum=0;
				}
			}
		}
        //否则就是偶数个,一个道理。
		else
		{
			for(int i=1;i<=m;i++)
			{
				cout<<"1";
				sum++;
				if(sum==n)
				{
					cout<<endl;
					sum=0;
				}
			}
		}
	}
	return 0;
 } 

我们再来个续集版

字符串与数组联动!

如果输入和输出颠倒我们如何输出呢?

思路:先将这个二维字符数组换成一行字符串,一次输入一行字符,记录行数,全部输入完就,输出行数和空格。后面就都是01。

一、循环字符串数组里的每一个字符如果它等于'0',计数就+1,如果改变了,不等于'0',那就说明这次0输入完了,我们就输出0的个数同时把计数=1因为不等于0,本身就有一个1不要漏了这个1,然后c就变成不等于0的1。

二、然后在循环1的个数如果='1',计数就+1,和一、一样最后c又变成0然后循环

这里就是一个循环利用计数因为01是交替的,先输入0在输入1,先输出0的个数在输出1的个数

#include <iostream>
using namespace std;
int main()
{
	string st,str="";//空字符串用来存放 
	int t=0,sum=0,c='0';
	while(cin>>st)
	{
		str+=st;//矩形字符数组变成一个字符串,一次输入一行 
		t++;//行数 
	}
	cout<<t<<' ';
	for(int i=0;i<=str.size();i++)//字符串长度 
	{
		if(str[i]==c)
		{
			sum++;
		}
		else 
		{
			c=str[i];//不连续,交换 
			cout<<sum<<' ';
			sum=1;
		}
	}
	return 0;
 } 

结束数组部分,大家平时要多敲代码,光有思路没有办法用代码实现是不行的,这说明练的还不够多,当然小白一开始也是敲不出来的,没关系慢慢来就好了,重要的是有耐心,和有思考,有着手去做题,如果觉得我的文章对你有用的话点个赞吧,欢迎评论区讨论谢谢。

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值