算法竞赛入门经典 第3章 数组和字符串 学习笔记

第一篇

数组

逆序输出

#include<iostream>
using namespace std;
#define maxn 105 //在算法竞赛中,常常难以精确计算出需要的数组大小,数组一般会声明得稍 大一些。在空间够用的前提下,浪费一点不会有太大影响。
int a[maxn];
int main()
{
	int x;
	int n=0;
	while(cin>>x)
	{
		a[n++]=x;   //a[n++]=x,它做了两件事:首先赋值a[n]=x,然后执行n=n+1。	
	}
	for(int i=n-1;i>=1;i--)
	{
		cout<<a[i]<<" ";
	}
	cout<<a[0]<<endl;
	return 0;
} 

对比一下这段代码

#include<iostream>
using namespace std;
#define maxn 100000000000
int main()
{
	int x;
	int n=0;
	int a[maxn]; //异常退出了 
	while(cin>>x)
	{
		a[n++]=x;   	
	}
	for(int i=n-1;i>=1;i--)
	{
		cout<<a[i]<<" ";
	}
	cout<<a[0]<<endl;
	return 0;
} 

比较大的数组应尽量声明在main函数外,否则程序可能无法运行
如果声明的是“int a[maxn],b[maxn]”,是不能赋值b=a的。
如果要从数组a复 制k个元素到数组b,可以这样做:memcpy(b,a,sizeof(int)k)。
当然,如果数组a和b 都是浮点型的,复制时要写成“memcpy(b,a,sizeof(double)
k)”。
另外需要注意的是, 使用memcpy函数要包含头文件string.h。
如果需要把数组a全部复制到数组b中,可以写得简单 一些:memcpy(b,a,sizeof(a))

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	int a[5]={1,2,3,4,5};
	int b[5];
	//从数组a复制k个元素到数组b
	memcpy(b,a,sizeof(int)*3);
	for(int i=0;i<3;i++)
	cout<<b[i]<<" ";
	return 0;
}

开灯问题,很有趣
开灯问题。有n盏灯,编号为1~n。第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3个人按下所有编号为3的倍数的开关(其中关掉的灯 将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?
输 入n和k,输出开着的灯的编号。k≤n≤1000。
样例输入: 7 3
样例输出: 1 5 6 7
【分析】用a[1],a[2],…,a[n]表示编号为1,2,3,…,n的灯是否开着。模拟这些操作即可。
注:代码里还控制让行末不输出空格
先贴书里给的代码:

#include<iostream>
#include<cstring>   //memset头文件
#define maxn 1010
using namespace std;
int a[maxn];
int main()
{
	int n,k,first=1;
	memset(a,0,sizeof(a));
	cin>>n>>k;
	for(int i=1;i<=k;i++) //人
	{
		for(int j=1;j<=n;j++) //灯
		{
			if(j%i==0) a[j]=!a[j];          //灯是人的倍数
		} 
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i])
		{
			if(first)
			first=0;
			else
			cout<<" ";
			cout<<i;
		}
	}
	cout<<endl;
	return 0;
} 

事实上,控制行末不输出空格,就是让空格在每一个数前面输出,第一个数最前面不输出空格,以后的数每个都是先输出空格再输出a[i]
“memset(a,0,sizeof(a))”的作用是把数组a清零,它也在string.h中定义。
虽然也能用for循环完成相同的任务,但是用memset又方便又快捷。
另一个技巧在输出:为了避免输出 多余空格,设置了一个标志变量first,可以表示当前要输出的变量是否为第一个。第一个变 量前不应有空格,但其他变量都有。
自己设计的:

#include<iostream>
using namespace std;
int main()
{
	int n,k;
	cin>>n>>k;
	int a[n]={0};
	//第一个人把所有的灯都打开了,就相当于是改变了所有1的倍数的灯的状态
	for(int i=1;i<=k;i++)
	{
		for(int j=1;i*j<=n;j++)
		{
			a[i*j]=!a[i*j];      //改变状态,用a[j]=!a[j]
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i]==1) cout<<i<<" ";
	} 
	return 0;
}
 posted on 2020-04-04 17:58  My_serendipity  阅读(169)  评论(0编辑  收藏  举报