2016年机试真题及题解
1.输入学生信息,姓名 成绩(成绩的数目不一定)
输出每个学生的姓名和平均成绩,按不及格课程数从大到小排好序输出,以及不及格课程数超过2的学生。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct stu{
string name;
int score[100];
int number;
double avg;
int unum;
};
// 定义学生按不及格科目数量的排序规则
bool cmp(stu x,stu y){
return x.unum>y.unum;
}
int main()
{
string str[100]; // 记录原始输入情况
int n=0; // 用于记录学生的数量
// 读取原始数据
while(getline(cin,str[n++]));
n--;
// 整理数据
stu s[100];
for(int i=0;i<n;i++){
int j=0;
// 提取姓名
while(str[i][j]!=' '&&str[i][j]!='\0')
s[i].name+=str[i][j++];
// 提取成绩
int count=0; // 记录成绩的数量
while(str[i][j]!='\0'){
int temp=0; // 存储局部成绩
while(str[i][++j]!=' '&&str[i][j]!='\0'){
temp=temp*10+(str[i][j]-'0');
}
s[i].score[count++]=temp;
}
s[i].number=count; // 记录每个学生的成绩数量
}
/*// 测试数据的输入及处理正确性
for(int i=0;i<n;i++){
cout<<s[i].name<<": ";
int t=0;
while(t<s[i].number)
cout<<s[i].score[t++]<<" ";
cout<<s[i].number;
cout<<endl;
}*/
// 计算学生的平均成绩及不及格科目数量
for(int i=0;i<n;i++){
int t=0, // 科目游标
sum=0, // 局部总成绩
u=0; // 不及格科目数量
while(t<s[i].number){
if(s[i].score[t]<60)
u++;
sum+=s[i].score[t++];
}
s[i].avg=sum/(s[i].number*1.0);
s[i].unum=u;
}
// 按照不及格成成数量从大到小排序
sort(s,s+n,cmp);
// 按照不及格成绩数量从大到小输出学生信息
for(int i=0;i<n;i++){
cout<<s[i].name<<": "<<s[i].avg<<endl;
}
// 输出不及格成绩超过两门的学生姓名
cout<<"不及格成绩超过两门的学生姓名为:"<<endl;
bool f=true; // 用于记录无不及格成绩超过两门的学生的情况
for(int i=0;i<n;i++){
if(s[i].unum>2){
f=false;
cout<<s[i].name<<" ";
}
}
if(f)
cout<<"无不及格成绩超过两门的学生!";
cout<<endl;
return 0;
}
2.输入字符串,输出字符串中包含的数字,比如2.3ABC0-2.3 输出 2.3 0 -2.3。
注意一些特殊的情况如+004.500值为+4.5。
#include<iostream>
#include<string>
using namespace std;
void f(int &op,string &temp,int &t){
if(temp==""){
if(t==1)
cout<<0<<" ";
op=0;
t=0;
return;
}
// 之前有有效数字
if(op==1){
cout<<"+"<<temp<<" ";
}
else if(op==-1){
cout<<"-"<<temp<<" ";
}
else
cout<<temp<<" ";
temp="";
op=0;
t=0;
}
int main(){
string str[100];
int n=0,k=0;
while(getline(cin,str[n++]));
n--;
while(k<n){
int i=0; // 字符串游标
int op=0; // 存储运算符
string temp=""; // 存储临时数值
string zero=""; // 存储连续的0
int flag=0; // 记录是否是小数部分
int t=0; // 记录是否有全0的特殊情况
while(str[k][i]!='\0'){
// 如果不是数字元素,直接忽略。
if((str[k][i]>='0'&&str[k][i]<='9')||str[k][i]=='+'||str[k][i]=='-'||str[k][i]=='.'){
/*
* 第一部分处理数字中的特殊符号。
*/
if(str[k][i]=='+'){
// 输出之前的数值
f(op,temp,t);
flag=0;
zero="";
op=1;
}
else if(str[k][i]=='-'){
// 输出之前的数值
f(op,temp,t);
flag=0;
zero="";
op=-1;
}
else if(str[k][i]=='.'){
// 处理+.123的特殊情况
if(temp=="")
op=0;
// 有多余的小数点
if(flag==1){
f(op,temp,t);
flag=0;
zero="";
}
// 有效的小数点
if(temp!=""){
// 标记一下,之后到达了小数部分。小数点不知道是否有效,先暂存。
flag=1;
}
if(temp==""&&t==1){
temp+='0';
flag=1;
}
}
/*
* 第二部分处理纯数字。
*/
else{
// 首部的无效0
if(temp==""&&str[k][i]=='0')
t=1;
// 小数点之后
else if(flag){
// 小数部分的0,不知道是否有效,先暂存
if(str[k][i]=='0'){
zero+='0';
}
// 小数点之后第一位非零数
else if(flag==1){
// 把之前暂存的小数点,0都加上
temp+='.';
temp+=zero;
zero="";
temp+=str[k][i];
flag++;
}
// 小数点之后多位
else{
temp+=zero;
zero="";
temp+=str[k][i];
}
}
// 整数部分
else{
temp+=str[k][i];
}
}
}
// 非字符忽略,并输出其前面的数字
else{
f(op,temp,t);
flag=0;
zero="";
}
// 向后检索
i++;
}
// 输出最后一个数
f(op,temp,t);
// 处理下一个字符串
k++;
cout<<endl;
}
return 0;
}
2017年机试真题及题解
1.身份证号的校验
身份证号码共18位,最后一位是校验位
A[18] : aaaaaabbbbbbbbccc d
校验的规则是如下
前十七位的权值分别是:W[17]:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
x=(A[0]*W[0]+A[1]*W[1]+A[2]*W[2]+...+A[16]*W[16]) mod 11
x和校验位y的对应规则对应如下:
x:0 1 2 3 4 5 6 7 8 9 10
y:1 0 x 9 8 7 6 5 4 3 2
若y等于d则身份证号码正确
输出格式:aaaaaabbbbbbbbcccd 正确
若y不等于d则身份证号码不正确
输出格式:应为:aaaaaabbbbbbbbcccy
测试用例:拿自己身份证实验一下就知道了
#include<iostream>
#include<string>
using namespace std;
int main()
{
int x=0;
char y;
// 前十七位的权值数组
int weight[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
// 转化表
char tran[17]={'1','0','x','9','8','7','6','5','4','3','2'};
string data; // 接收输入数据
cin>>data;
for(int i=0;i<17;i++)
x=(x+((data[i]-'0')*weight[i]))%11;
y=tran[x];
// 校验位正确
if(y==data[17])
cout<<data<<"正确"<<endl;
// 校验位错误
else{
cout<<"应为:";
for(int i=0;i<17;i++)
cout<<data[i];
cout<<y<<endl;
}
return 0;
}
2.二分查找
-36 -25 0 12 14 29 35 47 76 100(具体数字不一样,但是就是这个类型)
对上述十个数进行二分查找
测试用例:
请输入要查找的数据:14
14是第5个数,查找次数为1
请输入要查找的数据:-25
-25是第2个数,查找次数为2
请输入要查找的数据:121
查找失败
#include<iostream>
using namespace std;
int main()
{
int find;
int data[10]={-36,-25,0,12,14,29,35,47,76,100};
cout<<"请输入要查找的数据:";
while(cin>>find){
int low=0,high=9;
int number=-1,times=0;
while(low<=high){
times++;
int mid=(low+high)/2;
if(data[mid]==find){
number=mid+1;
break;
}
else if(data[mid]<find){
low=mid+1;
}
else{
high=mid-1;
}
}
if(number!=-1)
cout<<find<<"是第"<<number<<"个数,查找次数为"<<times<<endl;
else
cout<<"查找失败"<<endl;
cout<<endl;
cout<<"请输入要查找的数据:";
}
return 0;
}
3.建立一个学生信息系统,输入学生信息,输出有挂科同学的信息,再按照平均成绩从高到低排序输出
输入:
5
zhaoyi 70 80 90 240
qianer 65 32 77 174
sunsan 100 55 68 223
lisi 86 77 90 253
wangwu 100 59 66 225
输出:
*[qianer] 65 32 77
*[sunsan] 100 55 68
*[wangwu] 100 59 66
lisi 86 77 90
zhaoyi 70 80 90
wangwu 100 59 66
sunsan 100 55 68
qianer 65 32 77
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct stu{
string name;
int score[3];
int sum; // 总成绩
double avg; // 平均成绩
bool flag; // 是否挂科
};
bool cmp(stu x,stu y){
return x.avg>y.avg;
}
int main()
{
int n; // 学生数量
stu s[100];
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i].name;
cin>>s[i].score[0]>>s[i].score[1]>>s[i].score[2]>>s[i].sum;
if(s[i].score[0]<60||s[i].score[1]<60||s[i].score[2]<60)
s[i].flag=true;
else
s[i].flag=false;
s[i].avg=s[i].sum/3.0;
}
// 输出有挂科的同学
for(i=0;i<n;i++){
if(s[i].flag)
cout<<"*["<<s[i].name<<"]"<<" "<<s[i].score[0]<<" "<<s[i].score[1]<<" "<<s[i].score[2]<<endl;
}
cout<<endl;
// 按平均成绩从高到低输出
sort(s,s+n,cmp);
for(i=0;i<n;i++){
cout<<s[i].name<<" "<<s[i].score[0]<<" "<<s[i].score[1]<<" "<<s[i].score[2]<<endl;
}
return 0;
}