1.14 数组综合练习
1.14 数组综合练习
2034:【例5.1】反序输出
【题目描述】
输入n个数,要求程序按输入时的逆序把这n个数打印出来,
已知整数不超过100个。也就是说,按输入相反顺序打印这n个数。
【输入】输入一行共有n个数,每个数之间用空格隔开。
【输出】如题要求:一行,共有n个数,每个数之间用一个空格隔开。
【输入样例】1 7 3 4 5
【输出样例】5 4 3 7 1
【题解】
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e4;
int a[N], i=0;
int main() {
while(scanf("%d", &a[++i])!=EOF);//输入判断的一种模板,EOF=-1
for( i=i-1; i>=1; i--) printf("%d ", a[i]);
return 0;
}
2035:【例5.2】平移数据
【题目描述】
将a数组中第一个元素移到数组末尾,其余数据依次往前平移一个位置。
【输入】
第一行为数组a的元素个数;
第二行为n个小于1000的正整数。
【输出】
平移后的数组元素,每个数用一个空格隔开。
【输入样例】
10
1 2 3 4 5 6 7 8 9 10
【输出样例】
2 3 4 5 6 7 8 9 10 1
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
int a[N];
int main() {
int n; cin>>n;
for(int i=0; i<n; i++) cin>>a[i];
int temp=a[0];
for(int i=0; i<n; i++){
a[i]=a[i+1];
}
a[n-1]=temp;
for(int i=0; i<n; i++) cout<<a[i]<<" ";
return 0;
}
2036:【例5.3】开关门
【题目描述】
宾馆里有n(2≤n≤1000)个房间,从1~n编了号。
第一个服务员把所有的房间门都打开了,
第二个服务员把所有编号是2的倍数的房间“相反处理”,
第三个服务员把所有编号是3的倍数的房间作“相反处理”…,
以后每个服务员都是如此。
当第n个服务员来过后,哪几扇门是打开的。
(所谓“相反处理”是:原来开着的门关上,原来关上的门打开。)
【输入】房间数n。
【输出】一行,由小到大的打开门的房间序号,各序号之间用一个空格隔开。
【输入样例】100
【输出样例】1 4 9 16 25 36 49 64 81 100
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
bool a[N];//0 关, 1 开
int main() {
int n=100; cin>>n;
for(int i=1; i<=n; i++){
for(int j=i; j<=n; j++){
if(j%i==0) a[j]=!a[j];//逻辑取反
}
}
for(int i=1; i<=n; i++){
if(a[i]==1) cout<<i<<" ";
}
return 0;
}
2037:【例5.4】约瑟夫问题
【题目描述】
N个人围成一圈,从第一个人开始报数,数到M的人出圈;
再由下一个人开始报数,数到M的人出圈;…
输出依次出圈的人的编号。
【输入】输入N和M。
【输出】输出一行,依次出圈的人的编号。
【输入样例】8 5
【输出样例】5 2 8 7 1 4 6 3
【数据范围】对于所有数据,2≤N,M≤1000。
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
bool a[N];// 0 未出圈, 1 已出圈
int b[N];// 出圈顺序
int main() {
int n=8,m=5; cin>>n>>m;
int cnt=0,k=0,i=0;
while(cnt<n) { //全部出圈才结束
i++;
if(i>n) i=1;//队列人数报完,从头继续报数
if(a[i]==0) k++; //报数
if(k==m) b[++cnt]=i, k=0, a[i]=1;//出圈
}
for(int i=1; i<=n; i++) cout<<b[i]<<" ";
return 0;
}
2038:【例5.5】最大数位置
【题目描述】
输入n个整数,存放在数组a[1]至a[n]中,输出最大数所在位置(n≤1000)。
【输入】
第一行,数的个数n;
第二行,n个正整数,每个数在2^32-1之内。
【输出】
最大数所在位置。
【输入样例】
5
67 43 90 78 32
【输出样例】
3
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
long long a[N];
int main() {
long long n, maxn=-1, maxn_i=-1; cin>>n;
for(int i=1; i<=n; i++){
cin>>a[i];
if(maxn<a[i]) maxn=a[i], maxn_i=i;
}
cout<<maxn_i;
return 0;
}
2039:【例5.6】冒泡排序
【题目描述】
编程输入n(1≤n≤20)个小于1000非负整数,然后自动按从大到小的顺序输出。(冒泡排序)
【输入】
第一行,数的个数n;
第二行,n个非负整数。
【输出】
由大到小的n个非负整数,每个数占一行。
【输入样例】
5
2 5 8 6 12
【输出样例】
12
8
6
5
2
【题解】
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e4;
int a[N];
int main() {
int n; cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++){
for(int j=1; j<=n-i; j++){
if(a[j]<a[j+1]){//冒泡-每次比较相邻的两个元素
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(int i=1; i<=n; i++){
cout<<a[i]<<endl;
}
return 0;
}
2040:【例5.7】筛选法找质数
【题目描述】
用筛法求出n(2≤n≤1000)以内的全部质数。
【输入】输入n。
【输出】多行,由小到大的质数。
【输入样例】
10
【输出样例】
2
3
5
7
【题解】
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e4;
int primes[N], cnt=0;
int main() {
int n; cin>>n;
for(int i=2; i<=n; i++){
bool flag=1;
for(int j=2; j<i; j++){
if(i%j==0){
flag=0; break;
}
}
if(flag==1) primes[++cnt]=i;
}
for(int i=1; i<=cnt; i++){
cout<<primes[i]<<endl;
}
return 0;
}
1102:与指定数字相同的数的个数
【题目描述】
输出一个整数序列中与指定数字相同的数的个数。
【输入】
输入包含三行:
第一行为n,表示整数序列的长度(n≤100);
第二行为n个整数,整数之间以一个空格分开;
第三行包含一个整数,为指定的数字m。
【输出】
输出为n个数中与m相同的数的个数。
【输入样例】
3
2 3 2
2
【输出样例】
2
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
int a[N], cnt=0;
int main() {
int n; cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
int x; cin>>x;
for(int i=1; i<=n; i++){
if(x==a[i]) cnt++;
}
cout<<cnt;
return 0;
}
1103:陶陶摘苹果
【题目描述】
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。
苹果成熟的时候,陶陶就会跑去摘苹果。
陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,
请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。
【输入】
包括两行数据。第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)
分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。
第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),
表示陶陶把手伸直的时候能够达到的最大高度。
【输出】
包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
【输入样例】
100 200 150 140 129 134 167 198 200 111
110
【输出样例】
5
【题解】
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e4;
int a[N], cnt=0;
int main() {
for(int i=1; i<=10; i++) cin>>a[i];
int h; cin>>h;
for(int i=1; i<=10; i++){
if(a[i]<=h+30) cnt++;
}
cout<<cnt;
return 0;
}
1104:计算书费
【题目描述】
下面是一个图书的单价表:
计算概论 28.9元/本
数据结构与算法 32.7元/本
数字逻辑 45.6元/本
C++程序设计教程 78元/本
人工智能 35 元/本
计算机体系结构 86.2元/本
编译原理 27.8元/本
操作系统 43元/本
计算机网络 56元/本
JAVA程序设计 65元/本
给定每种图书购买的数量,编程计算应付的总费用。
【输入】
输入一行,包含10个整数(大于等于0,小于等于100),分别表示购买的《计算概论》、《数据结构与算法》、《数字逻辑》、《C++程序设计教程》、《人工智能》、《计算机体系结构》、《编译原理》、《操作系统》、《计算机网络》、《JAVA程序设计》的数量(以本为单位)。每两个整数用一个空格分开。
【输出】
输出一行,包含一个浮点数f,表示应付的总费用。精确到小数点后一位。
【输入样例】1 5 8 10 5 1 1 2 3 4
【输出样例】2140.2
【题解】
#include<iostream>
#include<iomanip>
#include<cstdio>
using namespace std;
const int N=1e4;
double a[N]={28.9,32.7,45.6,78,35,86.2,27.8,43,56,65}, money=0;
int main() {
for(int i=0; i<10; i++) {
int num; cin>>num;
money += a[i]*num;
}
cout<<fixed<<setprecision(1)<<money<<endl;
// printf("%.1lf",money);
return 0;
}
1105:数组逆序重存放
【题目描述】
将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。
【输入】
两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔。
【输出】
一行:输出逆序后数组的整数,每两个整数之间用空格分隔。
【输入样例】
5
8 6 5 4 1
【输出样例】
1 4 5 6 8
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
int a[N];
int main() {
int n; cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=n; i>=1; i--) cout<<a[i]<<" ";
return 0;
}
1106:年龄与疾病
【题目描述】
某医院想统计一下某项疾病的获得与否与年龄是否有关,需要对以前的诊断记录进行整理,按照0-18、19-35、36-60、61以上(含61)四个年龄段统计的患病人数占总患病人数的比例。
【输入】
共2行,第一行为过往病人的数目n(0<n<=100),第二行为每个病人患病时的年龄。
【输出】
按照0-18、19-35、36-60、61以上(含61)四个年龄段输出该段患病人数占总患病人数的比例,以百分比的形式输出,精确到小数点后两位。每个年龄段占一行,共四行。
【输入样例】
10
1 11 21 31 41 51 61 71 81 91
【输出样例】
20.00%
20.00%
20.00%
40.00%
【题解】
#include<iostream>
#include<iomanip>
#include<cstdio>
using namespace std;
const int N=1e4;
int a[N];
int main() {
int n; cin>>n;
for(int i=1; i<=n; i++){
int age; cin>>age;
if(age<=18) a[1]++;
else if(age<=35) a[2]++;
else if(age<=60) a[3]++;
else a[4]++;
}
for(int i=1; i<=4; i++){
cout<<fixed<<setprecision(2)<<100.0*a[i]/n<<"%"<<endl;
// printf("%.2lf%\n", 100.0*a[i]/n);
}
return 0;
}
1107:校门外的树
【题目描述】
某校大门外长度为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<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10,INF=0x3f3f3f3f;
int a[N];//0表示有树,1表示无树
int main() {
int l,m; cin>>l>>m;
for(int i=1; i<=m; i++) {
int u,v; cin>>u>>v;
for(int j=u; j<=v; j++) a[j]=1;//树被移栽
}
int ans=0;
for(int i=0; i<=l; i++) {
if(a[i]==0) ans++;
}
cout<<ans;
return 0;
}
1108:向量点积计算
【题目描述】
在线性代数、计算几何中,向量点积是一种十分重要的运算。
给定两个n维向量a=(a1,a2,...,an)和b=(b1,b2,...,bn),
求点积axb=a1xb1+a2xb2+...+anxbn。
【输入】
第一行是一个整数n(1≤n≤1000);
第二行包含n个整数a1,a2,...,an;
第三行包含n个整数b1,b2,...,bn;
相邻整数之间用单个空格隔开。每个整数的绝对值都不超过1000。
【输出】
一个整数,即两个向量的点积结果。
【输入样例】
3
1 4 6
2 1 5
【输出样例】
36
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
int a[N], b[N], ans=0;
int main() {
int n; cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) cin>>b[i];
for(int i=1; i<=n; i++) ans += a[i]*b[i];
cout<<ans;
return 0;
}
1109:开关灯
【题目描述】
假设有N盏灯(N为不大于5000的正整数),从1到N按顺序依次编号,
初始时全部处于开启状态;有M个人(M为不大于N的正整数)也从1到M依次编号。
第一个人(1号)将灯全部关闭,第二个人(2号)将编号为2的倍数的灯打开,
第三个人(3号)将编号为3的倍数的灯做相反处理(即将打开的灯关闭,将关闭的灯打开)。
依照编号递增顺序,以后的人都和3号一样,将凡是自己编号倍数的灯做相反处理。
请问:当第M个人操作之后,哪几盏灯是关闭的,
按从小到大输出其编号,其间用逗号间隔。
【输入】输入正整数N和M,以单个空格隔开。
【输出】顺次输出关闭的灯的编号,其间用逗号间隔。
【输入样例】10 10
【输出样例】1,4,9
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
bool a[N], flag=0;// 0 表示关闭, 1表示开启
int main() {
int n=10,m=10; cin>>n>>m;
for(int i=2; i<=m; i++){
for(int j=i; j<=n; j++){
if(j%i==0) a[j]=!a[j];
}
}
for(int i=1; i<=n; i++){
if(a[i]==0){
if(flag==0) flag=1, cout<<i;
else cout<<","<<i;
}
}
return 0;
}
1110:查找特定的值
【题目描述】
在一个序列(下标从1开始)中查找一个给定的值,输出第一次出现的位置。
【输入】
第一行包含一个正整数n,表示序列中元素个数。1 <=n<= 10000。
第二行包含n个整数,依次给出序列的每个元素,相邻两个整数之间用单个空格隔开。元素的绝对值不超过10000。
第三行包含一个整数x,为需要查找的特定值。x的绝对值不超过10000。
【输出】
若序列中存在x,输出x第一次出现的下标;否则输出-1。
【输入样例】
5
2 3 6 7 3
3
【输出样例】
2
【题解】
#include<iostream>
using namespace std;
const int N=1e4;
int a[N];
int main() {
int n; cin>>n;
for(int i=0; i<n; i++) cin>>a[i];
for(int i=0; i<n; i++){
if(a[i]==x) {
cout<<i+1; return 0;//结束程序
}
}
cout<<-1;
return 0;
}