简要题意

这道题就是要你维护一个学生成绩管理系统。

代码实现

程序设计

为了方便输出,我们定义了 println 函数:

void println(string s){
cout<<s<<'\n';
}

学生信息维护我用了一个结构体 Student

struct Student{
string sid,name;
int cid;
int chinese,mathematics,english,programming;
bool operator==(const Student &x) const{
return sid==x.sid && cid==x.cid && chinese==x.chinese && mathematics==x.mathematics && english==x.english && programming == x.programming;
}
};

存储学生我用了一个 vector(主存储)和一个 map(辅助存储,用于判断是否有重复的 SID):

vector<Student> v;
map<string,bool> duplicated;

然后就是主程序了:

#define judge(a,func) case a:func();break;
signed main(){
// freopen("1.out","w",stdout);
while(1){
main_menu();
int op;
cin>>op;
switch(op){
judge(1,add);
judge(2,remove);
judge(3,query);
judge(4,show_ranking);
judge(5,show_statisitics);
case 0:return 0;
}
}
}

主菜单部分

输出主菜单的部分,并不需要太大的难度。

void main_menu(){
println("Welcome to Student Performance Management System (SPMS).");
println("");
println("1 - Add");
println("2 - Remove");
println("3 - Query");
println("4 - Show ranking");
println("5 - Show Statistics");
println("0 - Exit");
println("");
}

添加学生部分

这一部分我们先读入学生信息,判 \(0\) 后再判重,如果都通过了就加进去。然后尾递归。

void add(){
println("Please enter the SID, CID, name and four scores. Enter 0 to finish.");
string sid;
cin>>sid;
if(sid=="0")return;
Student student;
student.sid=sid;
cin>>student.cid>>student.name>>student.chinese>>student.mathematics>>student.english>>student.programming;
if(duplicated[sid]){
println("Duplicated SID.");
}
else{
duplicated[sid]=1;
v.push_back(student);
}
add();
}

删除学生部分

这一部分先遍历所有学生,如果存在满足要求的学生就放进一个栈里。最后一个一个将栈中的元素取消存在 SID 标并删除。

void remove(){
println("Please enter SID or name. Enter 0 to finish.");
string str;
cin>>str;
stack<vector<Student>::iterator> removing;
if(str=="0")return;
int tot=0;
for(auto ite=v.begin();ite!=v.end();ite++){
if((*ite).sid==str || (*ite).name==str){
tot++;
duplicated[(*ite).sid]=0;
removing.push(ite);
}
}
while(!removing.empty()){
v.erase(removing.top());
removing.pop();
}
cout<<tot;
println(" student(s) removed.");
remove();
}

查询学生部分

码量较大的部分。我们先遍历所有学生,如果有满足条件的话:先将这个学生所在的班级的所有学生取出来,然后排一遍序,找到这个学生的排名,再输出信息。

int total(Student x){
return x.chinese+x.english+x.mathematics+x.programming;
} void query(){
println("Please enter SID or name. Enter 0 to finish.");
string str;
cin>>str;
if(str=="0")return;
for(Student i : v){
if(i.sid==str || i.name==str){
vector<Student> same_class;
for(Student j : v){
same_class.push_back(j);
}
sort(same_class.begin(),same_class.end(),[&](const Student &x,const Student &y){
return x.chinese+x.mathematics+x.english+x.programming>y.chinese+y.mathematics+y.english+y.programming;
});
int ret=0;
for(vector<Student>::size_type j=0;j<same_class.size();j++){
if(j>0&&total(same_class[j])==total(same_class[j-1])){}
else ret=j+1;
if(same_class[j]==i){
break;
}
}
cout<<ret<<' '<<i.sid<<' '<<i.cid<<' '<<i.name<<' ';
cout<<i.chinese<<' '<<i.mathematics<<' '<<i.english<<' '<<i.programming<<' ';
cout<<(i.chinese+i.mathematics+i.english+i.programming)<<' ';
printf("%.2lf\n",((double)((i.chinese+i.mathematics+i.english+i.programming))/4.0)+1e-5);
}
}
query();
}

显示排名部分

这一部分最简单,由于本题不需要我们输出排名,我们只需要输出提示信息即可。

void show_ranking(){
println("Showing the ranklist hurts students' self-esteem. Don't do that.");
}

班级统计部分

码量最大的部分。但是思维偏简单,直接遍历班级的学生(如果 CID 时 \(0\) 就是所有的学生)

,找到没有及格的和及格的,进行计数即可。

void show_statisitics(){
println("Please enter class ID, 0 for the whole statistics.");
int cid;cin>>cid;
int passed=0,failed=0;
double aver=0;
int cnt=0;
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
cnt++;
}
{
println("Chinese");
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
aver += i.chinese;
passed += (i.chinese >= 60);
failed += (i.chinese < 60);
}
aver /= cnt;
cout<<"Average Score: ";
printf("%.2lf\n",aver+1e-5);
cout<<"Number of passed students: "<<passed<<'\n';
cout<<"Number of failed students: "<<failed<<'\n';
println("");
}
{
aver=0;failed=0;passed=0;
println("Mathematics");
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
aver += i.mathematics;
passed += (i.mathematics >= 60);
failed += (i.mathematics < 60);
}
aver /= cnt;
cout<<"Average Score: ";
printf("%.2lf\n",aver+1e-5);
cout<<"Number of passed students: "<<passed<<'\n';
cout<<"Number of failed students: "<<failed<<'\n';
println("");
}
{
aver=0;failed=0;passed=0;
println("English");
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
aver += i.english;
passed += (i.english >= 60);
failed += (i.english < 60);
}
aver /= cnt;
cout<<"Average Score: ";
printf("%.2lf\n",aver+1e-5);
cout<<"Number of passed students: "<<passed<<'\n';
cout<<"Number of failed students: "<<failed<<'\n';
println("");
}
{
aver=0;failed=0;passed=0;
println("Programming");
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
aver += i.programming;
passed += (i.programming >= 60);
failed += (i.programming < 60);
}
aver /= cnt;
cout<<"Average Score: ";
printf("%.2lf\n",aver+1e-5);
cout<<"Number of passed students: "<<passed<<'\n';
cout<<"Number of failed students: "<<failed<<'\n';
println("");
}
println("Overall:");
int all=0,one=0,two=0,three=0,failed_all=0;
for(Student i : v){
if(i.cid!=cid&&cid!=0)continue;
int ret = (int)(i.chinese>=60)+(int)(i.mathematics>=60)+(int)(i.english>=60)+(int)(i.programming>=60);
if(ret>=1)one++;
if(ret>=2)two++;
if(ret>=3)three++;
if(ret>=4)all++;
if(ret==0)failed_all++;
}
cout<<"Number of students who passed all subjects: "<<all<<'\n';
cout<<"Number of students who passed 3 or more subjects: "<<three<<'\n';
cout<<"Number of students who passed 2 or more subjects: "<<two<<'\n';
cout<<"Number of students who passed 1 or more subjects: "<<one<<'\n';
cout<<"Number of students who failed all subjects: "<<failed_all<<'\n';
println("");
}

写在最后

这一道题,个人感觉并不是很难,\(30\) 分钟码代码 + \(20\) 分调试就做出来了。(最后发现时引号问题和删除问题)写完之后头脑清醒很多,收获了一个 UVA 调试工具 uDebug,还提升了英语水平(没有中文翻译,纯看英文题面)。

代码见此

最新文章

  1. Codeforces Round #346 (Div. 2) E F
  2. SVM+HOG特征训练分类器
  3. C++创建对象的两种方式
  4. 20145222黄亚奇《Java程序设计》第6周学习总结
  5. DIV与IDIV的用法
  6. RT-thread学习笔记(一)
  7. Edit 方法
  8. 为什么多数游戏服务端是用 C++ 来写
  9. [MSDN] 使用 SharePoint 2013 中的 JavaScript 库代码完成基本操作
  10. mac下的改装人生——第一次拆卸mbp,加入内存
  11. centos Minicom通信终端
  12. [NOIP2017] 逛公园
  13. Vue中使用Vue.component定义两个全局组件,用单标签应用组件时,只显示一个组件的问题和 $emit的使用。
  14. Deep learning with Python 学习笔记(9)
  15. C#面向对象(基础知识)
  16. POJ 3320 Jessica&#39;s Reading Problem (尺取法)
  17. oracle数据库数据库表空间查询及扩充
  18. CentOS6.9 网络设置
  19. Java多线程——线程封闭
  20. 白话浅说TCP/UDP面向连接,面向无连接的区别

热门文章

  1. Linux系统管理_磁盘管理——敬请期待!!!
  2. Linux之Docker-01
  3. PMM实现监控Mysql-MGR
  4. php注解使用示例
  5. 基于docker和cri-dockerd部署kubernetes v1.25.3
  6. 解决pip下载速度慢问题
  7. MYSQL数据库的导出和导入
  8. 从0到1搭建redis6.0.7
  9. Ajax(下)
  10. Node.js的学习(三)node.js 开发web后台服务