我们知道C语言是没有C++的集合set实现,所以需要自己写代码实现集合,需要设一个很大辅助数组标记元素是否已经出现。例如下题:
有 A,B,C 三个礼炮车,每个都要发射 21 枚礼炮,A 每隔 5s 发射一枚,B 每隔 6s 发射一枚,C 每隔 7s 发射一枚。假如每辆炮车都能准时发射,且如果有多辆炮车同时发射的话观众只能听到一声响,问观众一共可以听到几声响。
我们把时间轴都表示到一个数组flag里,flag[i]=0表示在i时刻没有响声,flag[i]=1表示在i时刻有响声,这样即使在某一时刻有多门炮在后面计算时也只计算一次。
由于最长时间为7*21,所以flag数组大小设为7*21+1
主要思路代码如下
int flag[148]; 这个数组需要一开始全部初始化为0
int i,ans=0;
for(i=1;i<=21;i++){
flag[5*i]=1; //5*i置1
flag[6*i]=1; //6*i置1
flag[7*i]=1; //7*i置1
//这样就算有多个置1结果也是1,所以不会重复,实现集合
}
计算
//计算flag数组元素为1的有多少个
for(i=1;i<=147;i++){
if(flag[i]==1)
ans++;
}
printf("%d",ans);
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树。现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。
同理我们设一个flag[10001]数组,flag[i]等于1表示i点有树,flag[i]等于0表示i点无树
主要思路代码如下:
int flag[10001]; //flag[i]=1表示i点有树,等于0表示i点无树
int i,j,left,right,ans;
for(i=0;i<=l;i++)
flag[i]=1; //先都初始化有树
for(i=0;i<m;i++){ //输入数据并清除区间内的树
scanf("%d%d",&left,&right);
for(j=left;j<=right;j++)
flag[j]=0;
}
//统计树数量
ans=0;
for(i=0;i<=l;i++){
if(flag[i]==1)
ans++;
}