(高校内部C++题库整理,内含C++期末原题)学的半会不会?从这篇开始,题目逐渐变得更有挑战性了,不过期末是随机组卷的话,这些经典例题也是一定要会的!!!一道题十分,C++绝不能挂科!!!
第六次实验
1、最大销售增幅 (中)
【问题描述】编写函数 maxIncrease,用于计算一个销售额序列中的最大销售增幅并返回。这里的销售额都是非负整数。
对于给定的销售额序列 A,假设序列 A 的长度为n (n>=2),最大销售额增幅是指满足0<=x<=y<n的A[y]-A[x]的最大值。
例如,销售额序列 11,3,5,7,9,2,4,6,8,10 的最大增幅为 8(在x=5,y=9时)。
函数 maxIncrease 需要将数组作为参数传入,在该数组中计算最大销售额增幅并返回。
【输入形式】首先输入销售额序列的长度,然后逐个输入销售额的值。
【输出形式】输出最大销售额增幅。
【样例输入】
6
12 120 34 97 6 134
【样例输出】
Please enter the length of sales series:
Please enter each sales amount separately:
The largest increase of sales is: 128
【样例说明】按系统提示,首先输入销售额序列的长度,然后再逐个输入销售额的值。输出最大销售额增幅。
【评分标准】 结果完全正确得10分,每个测试点5分。提交程序名为:max_increase.c或max_increase.cpp
注:审题时注意,最大“增幅”一定是“后减前”!
#include<iostream>
using namespace std;
int main()
{
int arr[100];
int n,temp,x,jian;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>x;
arr[i]=x;
}
for(int j=n;j<100;j++)
{
x=-1;
arr[j]=x;
}
for(int i1=0;i1<n;i1++)
{
for(int i2=i1;i2<n;i2++)
{
jian=arr[i2]-arr[i1];
if(i1==1)
{
temp=jian;
}
if(i1!=1&&jian>temp)
{
temp=jian;
}
}
}
cout<<temp;
return 0;
}
2、犯二的数字(中)
【问题描述】编写函数 silly,计算整数(不多于100位)犯二的程度并返回。
数字也可以“犯二”,一个整数“犯二的程度”定义为:该数字中包含2的个数与其位数的比值,如果这个整数是负数,则程度增加0.5倍,如果还是个偶数,则再增加1倍。
例如,数字−56782223456是个11位数,其中有3个2,是负数,也是偶数,则它的犯二程度为:3/11×1.5×2,约为0.818182。
函数 silly需要将数组作为形式参数,在该数组中计算数字的犯二程度并返回。
【输入形式】输入一个整数。
【输出形式】输出该整数的犯二程度。
【样例输入】
-56782223456
【样例输出】
Please enter an integer:
The stupidity degree of -56782223456 is: 0.818182
【样例说明】按系统提示,输入一个整数。输出该整数的犯二程度。
【评分标准】 结果完全正确得20分,每个测试点5分。提交程序名为:silly.c或silly.cpp
#include<iostream>
using namespace std;
float silly(int arr[],long long int n1,int wei)
{
float k=0;
float s;
for(int i1=0;i1<20;i1++)
{
if(arr[i1]==2)
{
k=k+1;
//cout<<k<<endl;
}
}
s=k/wei;
if(n1<0)
{
s=s*1.5;
}
if(n1%2==0)
{
s=s*2;
}
cout<<"The stupidity degree of "<<n1<<" is: "<<s;
return s;
}
int main()
{
long long int n,ws,n1;
int wei;
cout<<"Please enter an integer:"<<endl;
cout<<endl;
cin>>n;
n1=n;
if(n<0)
n=0-n;
int arr[20];
for(int i=0;i<20;i++)
{
ws=n%10;
wei=i+1;
if(n/10==0)
{
ws=n;
arr[i]=n;
for(i=i+1;i<20;i++)
{
arr[i]=-1;
}
break;
}
arr[i]=ws;
n=n/10;//注意位置!
//cout<<arr[i]<<endl;
}
silly(arr,n1,wei);
return 0;
}
- 整数的位数输出
- 用long long int, 防止溢出
- 可以将数组中多余的赋为-1
3、猴子选大王(难)
【问题描述】编写一个函数 king,实现猴子选大王的功能。该函数有两个形参,一个为猴子数组a,其中n个猴子分别占据下标为1~n的位置;另一个为数组长度n。
新猴王的选择方法是:让 N 只候选猴子围成一圈(最多100只猴子),从某位置起顺序编号为 1 ~ N 号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。
提示:
针对上述任务的描述,我们假设 N 只猴子分别占据数组 a 的下标从 1 ~ N 的位置(0号位置空着),从序号为1的猴子开始报数。返回值为猴王的序号。
可以把数组当作循环表来看,即第 N 个猴子的下一个猴子是第1个猴子。每次选出一个猴子,则对该位置进行标注,下次报数的时候跳过这些标注的位置即可。
【输入形式】输入猴子的个数。
【输出形式】输出猴王的序号。
【样例输入】
23
【样例输出】
Please input the number of monkey.
The monkey king is No.
8
【样例说明】按系统提示,输入猴子的个数。输出猴王的编号。
【评分标准】 结果完全正确得20分,每个测试点5分。提交程序名为:monkey_king.c或monkey_king.cpp
这版答案是网上提供的,我看不太懂,如果有大神明白希望能指点一下!
#include <iostream>
using namespace std;
// 函数king:猴子选大王
// 参数:a-猴子数组n-1个猴子分别占据下标为~n-1的位置,n-数组长度
// 返回值:新猴王的下标序号
int king(int a[], int n);
int main()
{
int n, a[1000], i; // 定义变量及数组,n-猴子数量,a-猴子数组
cout<<"Please input the number of monkey."<<endl;
cin >> n; // 输入猴子数量,n>0
// 初始化猴子数组,n 个猴子分别占据 n 个位置
a[0] = 0; // 0号位置没有猴子
for(i = 1;i <= n; i++)
a[i] = i;
// 选大王啦
i = king(a, n );
cout <<"The monkey king is No."<<endl<< i << endl;
return 0;
}
int king(int a[], int n)
{
// 请在此添加代码,实现函数king
/********** Begin *********/
int i,j,t=0;
for(i=0;i<=n;i++)
a[i]=1;
for(i=1;i<=n;i++)
{
j=1;
while(j<=3)
{
t=(t+1)%n;
if(a[t]==1)j++;
}
a[t]=0;
}
return t;
/********** End **********/
}
答案2:
#include<iostream>
using namespace std;
int king(int arr[],int n)
{
int flag=0;//计数用,到3标记
//啊啊啊啊啊啊初始的flag=0!!!
int out;//退出循环的条件
int t;//最后剩下的那个,输出
for(int i1=0;;i1++)//用来遍历数组
{
//只有arr[i1]不等于0时,flag+1
if(arr[i1]!=0){
flag++;
//之后flag变为1
cout<<"flag="<<flag<<endl;//验证下flag变没变
}
if(flag==3)
{
out=out+1;//踢出去一个数
//cout<<"arr"<<i1<<"=0"<<endl;//浅浅验证下程序是否将arr[l1]赋为0了
arr[i1]=0;//把这个被标记的数值赋为0,以后就不再参与改变flag,即跳过了
flag=0;//flag=3时要重新赋值进入下一个循环
}
if(i1==n)
i1=0; //到数组尾部时,返回第一个
if(out==n-1)
break;//当只剩下最后一个不等于0的元素,结束循环(可以用while,忘了咋用了)
}
for(int j=0;j<n;j++)
{
//cout<<"ziuhou"<<arr[j]<<endl;
if(arr[j]!=0)
{
t=j;
}
}
return t;
}
int main()
{
int arr[100];
int n,t;
cin>>n;
//给猴子标号,除了被标的都=0,直接跳过
arr[0]=0;
for(int i=1;i<=n;i++)
{
arr[i]=i;
}
for(int j=(n+1);j<100;j++)
{
arr[j]=0;
}
//jianyan
t=king(arr,n);
cout<<" "<<t;
return 0;
}
第七次实验
1、计算两个日期之间的天数(中)
这个题不算太容易哈,但是和前面的输出日历比起来,这简直是小巫见大巫啦
【问题描述】小宗想知道两个日期之间所间隔的天数,他希望有一个日期计算器,输入两个日期后能够自动计算之间的天数。要求:设计相应的函数完成天数的计算,在主函数中验证正确性。定义一个is_run函数用于判断是否是闰年,在主函数中定义一个数组用于记录一年中每个月份的天数。
【输入形式】按照年月日的顺序输入两个日期,年月日之间用一个空格分隔。
【输出形式】输出两个日期之间的天数,即一个整数,整数后不需要换行。
【样例输入】
2019 8 16
2022 4 24
【样例输出】
982
【样例说明】按照年月日的顺序输入两个日期,年月日之间用一个空格分隔。输出两个日期之间的天数,即一个整数,整数后不需要换行。
【评分标准】 结果完全正确得15分,每个测试点5分。提交程序名为:date_cal.c或date_cal.cpp
#include<iostream>
using namespace std;
bool is_run(int year)
{
if(year%4==0&&year%100!=0||year%400==0)
{
return true;
}
else
return false;
}
int year_day(int year)
{
int yearday;
if(is_run(year))
{
yearday=366;
}
else
yearday=365;
return yearday;
}
int month_day(int year,int monthnum)
{
int monthday;
//用case也行
/*switch(monthnum)
{
case 2:
if(is_run(year))
{
monthday=29;
return monthday;}
else
{
monthday=28;
return monthday;}
case 4:
case 6:
case 9:
case 11:
monthday=30;
return monthday;
default:
monthday=31;
*/
if(monthnum==2)
{
if(is_run(year))
{
monthday=29;
return monthday;}
else
{
monthday=28;
}}
else if(monthnum==4||monthnum==6||monthnum==9||monthnum==11)
{
monthday=30;
}
else monthday=31;
return monthday;
}
int total_day(int y1,int y2,int m1,int m2,int d1,int d2)
{
int tyd=0;
int tmd1=0;
int tmd2=0;
int tdd1=0;
int tdd2=0;
for(int i1=y1+1;i1<y2;i1++)
{
tyd+=year_day(i1);
}
for(int i2=m1+1;i2<=12;i2++)
{
tmd1+=month_day(y1,i2);
}
for(int i3=1;i3<m2;i3++)
{
tmd2+=month_day(y2,i3);
}
int a1=month_day(y1,m1);
tdd1=a1-d1;
//cout<<"输出monthday1"<<a1;
tdd2=d2;
//cout<<"年"<<tyd<<endl<<"月天数一"<<tmd1<<endl<<"月天数二"<<tmd2<<endl;
//cout<<"日一"<<tdd1<<"ri二"<<tdd2<<endl;
int totalday=tyd+tmd1+tmd2+tdd1+tdd2;
return totalday;
}
int main()
{
int y1,m1,d1;
cin>>y1>>m1>>d1;
cout<<endl;
int y2,m2,d2;
cin>>y2>>m2>>d2;
total_day(y1,y2,m1,m2,d1,d2);
int a=total_day(y1,y2,m1,m2,d1,d2);
cout<<a;
return 0;
}
整体思路参考日历
2、函数重载实现月工资计算 (易)
【问题描述】设计一菜单程序,利用函数重载实现员工月工资的计算,计算方法如下:
(1)管理人员的月工资 = 月薪 - 缺勤天数 × 月薪 ÷ 22;
(2)销售人员的月工资 = 底薪 + 销售金额 × 提成比例;
(3)计件工人的月工资 = 产品件数 × 每件报酬;
(4)计时工人的月工资 = 工作小时 × 小时报酬。
【输入形式】首先输入职工类别。按照职工类别,分情况输入:管理人员输入月薪和缺勤天数;销售人员输入底薪、销售金额和提成比例;计件工人输入产品件数和每件报酬;计时工人输入工作小时和小时报酬。
【输出形式】员工月工资。
【样例输入】
2
3000 40000 0.1
【样例输出】
Please select...
1: Manager.
2: Sales Man.
3: Pieces Worker.
4: Hour-Worker.
Others: Quit
7000
【样例说明】首先输入职工类别。按照职工类别,分情况输入:管理人员输入月薪和缺勤天数;销售人员输入底薪、销售金额和提成比例;计件工人输入产品件数和每件报酬;计时工人输入工作小时和小时报酬。输出员工月工资。
【评分标准】 结果完全正确得15分,每个测试点3分。提交程序名为:salary.c或salary.cpp
#include<iostream>
using namespace std;
void ma(float mon,float day)
{
float salary;
salary=mon-day*(mon/22);
cout<<salary;
}
void sa(int mon,int jin,float ti)
{
float salary;
salary=mon+jin*ti;
cout<<salary;
}
void ji(int jian,int chou)
{
float salary;
salary=jian*chou;
cout<<salary;
}
void shi(int hour,int bao)
{
float salary;
salary=hour*bao;
cout<<salary;
}
int main()
{
int type;
cin>>type;
int y=1;
if(type==1)
{
float mon,day;
cin>>mon>>day;
//int shu(y);
cout<<"Please select..."<<endl;
cout<<"1: Manager."<<endl;
cout<<"2: Sales Man."<<endl;
cout<<"3: Pieces Worker."<<endl;
cout<<"4: Hour-Worker."<<endl;
cout<<"Others: Quit"<<endl;
ma(mon,day);
}
else if(type==2)
{
int mon2,jin;
float ti;
cin>>mon2>>jin>>ti;
cout<<"Please select..."<<endl;
cout<<"1: Manager."<<endl;
cout<<"2: Sales Man."<<endl;
cout<<"3: Pieces Worker."<<endl;
cout<<"4: Hour-Worker."<<endl;
cout<<"Others: Quit"<<endl;
//int shu(y);
sa(mon2,jin,ti);
}
else if(type==3)
{
int jian,chou;
cin>>jian>>chou;
cout<<"Please select..."<<endl;
cout<<"1: Manager."<<endl;
cout<<"2: Sales Man."<<endl;
cout<<"3: Pieces Worker."<<endl;
cout<<"4: Hour-Worker."<<endl;
cout<<"Others: Quit"<<endl;
//int shu(y);
ji(jian,chou);
}
else if(type==4)
{
int hour,bao;
cin>>hour>>bao;
cout<<"Please select..."<<endl;
cout<<"1: Manager."<<endl;
cout<<"2: Sales Man."<<endl;
cout<<"3: Pieces Worker."<<endl;
cout<<"4: Hour-Worker."<<endl;
cout<<"Others: Quit"<<endl;
//int shu(y);
shi(hour,bao);
}
else
{
cout<<"Please select..."<<endl;
cout<<"1: Manager."<<endl;
cout<<"2: Sales Man."<<endl;
cout<<"3: Pieces Worker."<<endl;
cout<<"4: Hour-Worker."<<endl;
cout<<"Others: Quit"<<endl;
}
return 0;
}
写起来确实有点麻烦,但总体思路还是简单的(函数重载的话要把上面的函数名改成一样的)
3、合并数组,排列新数组(中)
【问题描述】合并两个整型数组,并按照由小到大的顺序排列新数组的元素。编写如下函数,合并两个整型数组,形成一个新的各元素由小到大排列好的数组。
void merge(const int list1[], int size1, const int list2[], int size2, int list3[])
【输入形式】按照提示分别输入前两个数组的长度及各元素。
【输出形式】输出排列好的新数组。
【样例输入】
5
-3 0 189 543 38
6
-68 33 296 3 12 975
【样例输出】
Enter size1:
Enter list1:
Enter size2:
Enter list2:
The merged list is:
-68 -3 0 3 12 33 38 189 296 543 975
【样例说明】按照提示分别输入前两个数组的长度及各元素。输出排列好的新数组。
【评分标准】 结果完全正确得15分,每个测试点5分。提交程序名为:array_merge.c或array_merge.cpp
STL确实好用
#include<iostream>
#include<deque>
#include<algorithm>
using namespace std;
int main()
{
int l1,l2;
deque<int>d1;
deque<int>d2;
deque<int>d3;
cout<<"Enter size1:"<<endl;
cin>>l1;
cout<<endl;
cout<<"Enter list1:"<<endl;
for(int i1=0;i1<l1;i1++)
{
int a;
cin>>a;
d1.push_back(a);
}
cout<<endl;
cout<<"Enter size2:"<<endl;
cin>>l2;
cout<<endl;
cout<<"Enter list2:"<<endl;
for(int i2=0;i2<l2;i2++)
{
int b;
cin>>b;
d1.push_back(b);
}
cout<<endl;
sort(d1.begin(),d1.end());
int l3=l1+l2;
cout<<"The merged list is:"<<endl;
for(int i3=0;i3<l3;i3++)
{
cout<<d1[i3];
cout<<" ";
}
return 0;
}
第八次实验
1、用指针做形参求小数部分 (易)
【问题描述】编写如下原型的函数:void split (double x, int *iPart, double *fPart); 提取出实数x的整数部分与小数部分,分别放于iPart与fPart处,由于形参iPart与fPart都是指针,从而可实现将这两个结果“带回”到主函数中。自定义main()函数,并在其中调用split函数。
【输入形式】按照提示输入一个实数。
【输出形式】分别输出该实数的整数部分和小数部分。
【样例输入】
-12.3
【样例输出】
Please enter a real number:
integer part = -12, decimal part = -0.3
【样例说明】按照提示输入一个实数。分别输出该实数的整数部分和小数部分。
【评分标准】 结果完全正确得15分,每个测试点5分。提交程序名为:split.c或split.cpp
#include<iostream>
using namespace std;
void split(double x,int *ipart,double *fpart)
{
*fpart=x-(int)x;
*ipart=(int)x;
}
int main()
{
double num;
cin>>num;
int ipart;
//int *ipart;
//*ipart=&ipart;
double fpart;
//double *fpart;
split(num,&ipart,&fpart);
cout<<ipart<<" "<<fpart;
return 0;
}
注:
不用单独定义指针,直接取地址符就行
这里要加上‘*’!
*fpart=x-(int)x; *ipart=(int)x;
2、 指针做形参找子串最后一次出现的头字符位置(难)
【问题描述】编制具有如下原型的函数:char *findLast (char *sourcestr, char *substr); 该函数要返回源串sourceStr中最后一次出现subStr子字符串的头字符位置。而后编制主函数,输入两个字符串,将它们用作实参来调用这个函数,如果返回NULL则输出-1,否则输出子字符串出现时头字符在原字符串的下标,每个结果占一行。要求实现程序中不可使用“string.h”头文件内有关寻找子串的标准库函数。
【输入形式】分别输入源串sourceStr,子字符串subStr。
【输出形式】输出子字符串subStr最后一次在源串sourceStr中出现的位置。
【样例输入】
adjljdlajflkjifjifngifngimdsn if
【样例输出】
Please enter two strings:
20
【样例说明】分别输入源串sourceStr,子字符串subStr。输出子字符串subStr最后一次在源串sourceStr中出现的位置。
【评分标准】 结果完全正确得20分,每个测试点10分。提交程序名为:findLast.c或findLast.cpp
#include<cstring>
using namespace std;
char*findlast(char*sousestr,char*substr);//函数返回的是指针?
int main()
{
char str[100],substr[20];
char*p;
p=str;
cout<<"Please enter two strings:"<<endl;
cin>>str;
cin>>substr;
p=findlast(str,substr);
if(p==NULL)//相当于0
cout<<"-1"<<endl;
else
cout<<p-str<<endl;
return 0;
}
char*findlast(char*sourcestr,char*substr)
{
int len1=0,len2=0;
len1=strlen(sourcestr);
len2=strlen(substr);
char*p1=sourcestr+len1-1,*p2=substr+len2-1;
if(len1<len2)
return NULL;
else
{
while(*p1!=*(sourcestr-1)&&*p2!=*(substr-1))
{
if(*p1==*p2)
{
p2--;
}
else
{
p2=substr+len2-1;
}
p1--;
}
if(*p2==*(substr-1))
return p1+1;
else return NULL;
}
}
3、指针做形参求实数的和与差(易)
【问题描述】编写程序计算输入的两个实数的和与差,要求定义一个函数void sum_diff (float op1, float op2, float *psum, float *pdiff),其中,op1和op2是输入的两个实数,psum和pdiff是计算得出的和与差。自定义main()函数,并在其中调用sum_diff函数。
【输入形式】按照提示分别输入两个实数。
【输出形式】分别输出两个实数的和与差。
【样例输入】
643.428 -279,64
【样例输出】
Please enter two real numbers:
sum=364.428,minus=922.428
【样例说明】按照提示分别输入两个实数。分别输出两个实数的和与差。
【评分标准】 结果完全正确得15分,每个测试点5分。提交程序名为:sum_diff.c或sum_diff.cpp
#include<iostream>
using namespace std;
void sum_diff(float op1, float op2, float *psum, float *pdiff)
{
*psum=op1+op2;
*pdiff=op1-op2;
}
int main()
{
float a,b;
cin>>a>>b;
float he,cha;
sum_diff(a,b,&he,&cha);
cout<<he<<" "<<cha;
return 0;
}