校门外的树
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,…,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入
每组输入数据的第一行有两个整数L(1<=L<=10000)和M(1<=M<=100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
数据规模:对于20%的数据,区域之间没有重合的部分;对于其它的数据,区域之间有重合的情况。
输出
每组输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例输入
500 3
150 300
100 200
470 471
样例输出
298
代码实现
#include <iostream>
using namespace std;
int main(){
int l,i,start,n,end,a[10001] = {0};
cin >> l >> n;
for(i = 0;i <= 1000;i++){
a[i] = 1;
}
for(i = 0;i < n;i++){
cin >> start >> end;
for(int j = start;j <= end;j++){
a[j] = 0;
}
}
int count = 0;
for(i = 0;i <= l;i++){
if(a[i] == 1) count++;
}
cout << count << endl;
return 0;
}
2 假设有n盏灯(n为部大于5000的正整数),从1~n按顺序依次编号,初始时全部处于开启状态; 有m个人(m为不大于n的正整数)也从1~m依次编号。
第一个人(1号)将全部灯都关闭,第二个人将编号为2的倍数的灯打开,第三个将编号为3的倍数的灯做相反处理。
请问:当第m个人操作之后,哪几盏灯是关闭的,按从小到大输出其编号,其间用逗号隔开
输入:
输入正整数n和m,以单个空格隔开
输出:
顺次输出关闭的灯的编号,其间用逗号隔开
样例输入:
10 10
样例输出:
1,4,9
参考程序:
#include <iostream>
using namespace std;
int main(){
int n,m,i;
int light[5001];
for(i = 1;i <= 5000;i++){
light[i] = 1;
}
cin >> n >> m;
for(i = 1;i <= n;i++){
for(int j = i;j <= n;j++){
if(j % i == 0) light[j] = !light[j];
}
}
int z = 1;
for(i = 1;i <= n;i++){
if(!light[i]){
if(z) z = 0;
else
cout << ",";
cout << i;
}
}
cout << endl;
return 0;
}
本题的一个关键点就是头一个不输出的操作:
首先设置标记z =1;
if(z) z = 0;
只有第一次回跳过,完成了首次不输出逗号的操作
3 .医院采样了某临床病例治疗期间的白细胞数量样本n份,用于分析某种新抗生素对该病例的治疗效果。为了降低分析误差,要先从这n份样本中去除一个数值最大的 样本和一个数值最小的样本,然后将剩余n-2个有效样本的平均值作为分析指标。同时,为了观察该抗生素的疗效是否稳定,还要给出该平均值的误差,即所有有 效样本(即不包括已扣除的两个样本)与该平均值之差的绝对值的最大值。 现在请你编写程序,根据提供的n个样本值,计算出该病例的平均白细胞数量和对应的误差。
输入:
输入的第一行是一个正整数n(2 < n <= 300),表明共有n个样本。
以下共有n行,每行为一个浮点数,为对应的白细胞数量,其单位为10^9/L。数与数之间以一个空格分开。
输出:
输出为两个浮点数,中间以一个空格分开。分别为平均白细胞数量和对应的误差,单位也是10^9/L。计算结果需保留到小数点后2位。
样例输入
5
12.0
13.0
11.0
9.0
10.0
样例输出
11.00 1.00
提示
为避免浮点精度误差过大,请使用double类型。计算误差时,要使用下标,而非值,作比较。
参考程序:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main(){
float data[300] ={0};
int n,i,p,q;
cin >> n;
for(i = 0;i < n;i++) cin >> data[i];
float max = data[0],min = data[0],sum = data[0],w;
for(i = 1;i < n;i++){
sum += data[i];
if(data[i] > max){ max = data[i]; p = i;}
if(data[i] < min){ min = data[i]; q = i;}
}
sum = sum - max - min;
w = sum/(n-2);
cout << fixed << setprecision(2) << w << " ";
max = abs(data[0] - w);
data[p] = data[q] = w;
for(i = 1;i < n;i++){
int temp = abs(data[i] - w);
if(temp > max) max = temp;
}
cout << max << endl;
return 0;
}
4 最长平台
已知一个已经从小到大排序的数组,这个数组的一个平台(plateau)就是连续的一串值相同的元素,并且这一串元素不能在延伸。
输入
第一行有一个整数n,为数组元素个数,第2行有n个整数,整个整数和之间以一个空格分开
输出
最长平台的长度
样例输入
10
1 2 2 3 3 3 4 5 5 6
样例输出
3
代码实现
#include <iostream>
using namespace std;
int main(){
int n,i,count = 0,max = -1,data[100001] = {0},k;
cin >> n;data[0] = -1;
for(i = 1;i <= n;i++){
cin >> data[i];
if(data[i] == data[i-1]) k++;
else k = 1;
if(k > max) max = k;
}
cout << max << endl;
}
这段代码实在巧妙,还是复现一下
5.整数去重
给定含有n个整数的序列,要求对这个序列进行去重操作.所谓去重,就是对这个序列中每个重复出现的数,只保留该数第一次出现的位置,删除其余位置
输入:
包含两行:
第一行包含一个正整数n(1 <= n <= 20,000)表示第二行序列中数字的个数
第二行包含n个整数,每个整数之间以一个空格隔开
样例输入:
5
10 12 93 12 75
样例输出:
10 12 93 75
代码实现:
#include <iostream>
using namespace std;
int main(){
int data[20001] = {0},i,n;
bool flag[20001];
for(i = 0;i < 20001;i++) flag[i] = true;
cin >> n;
for(i = 0;i < n;i++) cin >> data[i];
for(i = 0;i < n;i++){
if(flag[i])
for(int j = i + 1;j < n;j++)
if(data[j] == data[i])
flag[j] = false;
}
for(i = 0;i < n;i++){
if(flag[i])
cout << data[i] << " ";
}
cout << endl;
return 0;
}
对于查重问题用一个和data相等长度的bool型数组存储重复和不重复信息,然后根据信息输出数值即可.学到了