算法竞赛入门经典 第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;
}