当前位置: 首页 > article >正文

全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之一维数组(应用技巧)

前面对数组的定义、初始化、遍历、修改和应用做了介绍,接下来对数组的应用技巧进一步讲解。

一、一维数组的应用技巧1:对数组进行初始化

数组的初始化方法通常有3种:

1、在定义数组时对全部数组元素赋予初值。例如: int a[10]={0,1,2,3,4,5,6,7,8,9};将数组元素的初值依次放在一对花括号内。经过上面的定义和初始化之后, a[0]=0, a[1]=1, a[2]=2, a[3]=3, a[4]=4, a[5]=5, a[6]=6,a[7]=7,a[8]=8,a[9]=9。

2、可以只给一部分元素赋值。例如: int a[10]={0,1,2,3,4};定义a数组有10个元素,但花括号内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值默认为0。

3、在对全部数组元素赋初值时,可以不指定数组长度。例如: int a[5]={1,2,3,4,5};可以写成int a[]={1,2,3,4,5};

除此之外还有一种更为快捷的写法,使用memset函数,该函数是基于对字节的操作(一个整型变量占4个字节的存储空间,每个字节是8位二进制数,那么一个整型变量是32位二进制数)。这种方法是给每个字节赋在[0,255]的值,那么首先来介绍sizeof函数,其作用是计算一个变量占多少字节。格式为:sizeof(变量名)。例如:


int a;
cout<<sizeof(a)<<endl;

运行结果:输出4,定义一个整型变量a,输出变量a所占的字节数,运行结果表示变量a占4个字节。

再如:


int a[105];
cout<<sizeof(a)<<endl;

运行结果:输出420,定义一个长度为105的整型数组,输出该数组所占的总字节数,运行结果表示数组a占420个字节(105*4)。

memset函数,其作用是将数组中每个字节都赋值一个数。格式为:

memset(数组名,要初始化的值赋值,sizeof(数组名))。

例如:


int a[105];
memset(a,0,sizeof(a));

定义一个长度为105的整型数组a,将数组a中的每个字节都赋值为0,一个整数类型占4个字节,由于每个字节都是0,则一个整型数字的结果就为0。

再如:

memset(a,1,sizeof(a));

将数组a中的每个字节都赋值为1,那么一个整型数字的结果是多少呢?这个问题好像不是很容易,同时把具体字节赋值过程完整地写出来,1写成8位二进制数就是00000001.一个整数是4个字节,每个字节都是00000001,则其32位二进制数就是00000001000000010000000100000001,转换为十进制数便是16843009.因此,数组的每一个存储空间的值是16843009。这里不少同学会误以为memset(a,1,sizeof(a));表示数组中所有变量都为1。下面给出几个一般的赋值结果:

1)、memset(a,0,sizeof(a));表示将数组中每个元素赋值为0;

2)、memset(a,-1,sizeof(a));表示将数组中每个元素赋值为-1;

3)、memset(a,127,sizeof(a));表示将数组中每个元素赋值为2139062143,这是一个很大的数,接近int类型的上限;

4)、memset(a,0x3f,sizeof(a));表示将数组中每个元素赋值为1061109567(0x3f是十六进制表示,等同于十进制的63,该数的2倍接近int类型的上限。

二、一维数组应用技巧2:打标记

下面通过例子来引入打标记的思想

问题描述:

假设现在有编号1-n的n个白色盘子,小明准备在一些盘子上涂颜色,可能会重复选择某一些盘子涂颜色,问最后哪些盘子还是白色,并按编号从小到大输出。

输入格式:

输入共包含两行:第一行包含两个整数n和m,n表示盘子的个数,m表示将进行m次涂色;第二行包含m个整数,整数之间用空格隔开,每个整数表示每次涂色的盘子编号,盘子可能重复。

输出格式:

输出一行,按编号从小到大输出没有涂颜色的盘子的编号,编号之间用空格隔开。

输入输出样例:

输入样例1

输出样例1

6 10

1 3 5 1 6 3 1 5 3 1

2 4

输入样例2

输出样例2

8 10

1 3 5 1 6 3 1 5 3 1

2 4 7 8

问题分析:

根据题意,刚开始盘子全部为白色,对盘子操作涂色,对于这一类问题采用打标记的思想,采用数组下标对应盘子的编号,数组元素的值表示颜色状态,即用数组a[i]表示编号为i盘子的涂色状态,a[i]=1(bool类型),表示涂了颜色(bool值为true),a[i]=0表示没有涂过颜色(bool值为 false),重复涂色的盘子最终状态依然为1。这样问题就变成了涂色的盘子标记为1,没有涂过色的盘子标记为0。假设盘子编号分别为1 2 3 4 5 6 …… n,起始状态都为白色,a[i]的值为0,表示都未涂过颜色,然后循环输入m次操作,将下标出现的数组元素表示涂色,这时将数组元素值修改为1,最后循环判断,如果a[i]为0,表示未涂色,依次输出i。具体程序代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
	bool a[105];//定义标记数组 
	memset(a,0,sizeof(a));//将标记数组的起始值设置为false 
	int n,m;//定义盘子数变量n和涂色次数m 
	cin>>n>>m;//输入n和m的值 
	for(int i=0;i<m;i++){//进行m次涂色操作 
		int tmp;//定义涂色的盘子编号变量tmp 
		cin>>tmp;//输入tmp的值 
		a[tmp] = 1; //修改该盘子的标记 
	}
	for(int i=1;i<=n;i++){//从第1个盘子开始到最后一个盘子n 
		if(!a[i]){//判断该盘子的标记是否被修改过 
			cout<<i<<' ';//输出未涂色的盘子 
		}
	}
	return 0;
} 

http://www.kler.cn/a/508366.html

相关文章:

  • python中的RPA->playwright自动化录制脚本实战案例笔记
  • 【AI学习】地平线首席架构师苏箐关于自动驾驶的演讲
  • Git学习笔记
  • 正则表达式 匹配特定字符后的所有字符
  • LLM - 大模型 ScallingLaws 的 Causal/Masked (PLM) 目标系数差异 教程(2)
  • js-判断一个object(对象)是否为空
  • linux 国产化命令
  • 算法随笔_10: 供暖器
  • Linux网络 TCP socket
  • 一体机cell服务器更换内存步骤
  • java 小红书源码 1:1还原 uniapp
  • 小识MySQL中的OLTP和OLAP
  • 全类别机器人传感器模块推荐
  • RK3568笔记七十五:FFMPEG交叉编译
  • Rnote:Star 8.6k,github上的宝藏项目,手绘与手写画图笔记,用它画图做笔记超丝滑,值得尝试!
  • 如何在 ASP.NET Core 中实现速率限制?
  • [JavaScript] 变量与数据类型:从基础到进阶
  • C++第十五讲:异常
  • 春秋杯-WEB
  • maven 微服务项目多 包版本问题
  • 【张雪峰高考志愿填报】合集
  • 职场沟通与行为
  • C++: : error: expected type-specifier before ‘;‘ token
  • 计算机网络 (43)万维网WWW
  • 2025年1月17日(点亮三色LED)
  • Three.js图像拼图技术