题目来源:https://cn.vjudge.net/problem/UVA-12412//题目太长不想复制
题意:
写一个学生成绩管理系统 (SPMS).
SID:10位数字
CID:不超过20的整数
name:不超过10位的一个字符串
four scores(Chinese, Mathematics, English and Programming):不超过100的自然数
1 - Add 加入数据
2 - Remove 删除数据
3 - Query 查询数据
4 - Show ranking 没用的只是输出一行话
5 - Show Statistics 输出总数据
0 - Exit 退出系统
评析:
此题很坑很不错,平台里的学生人数是0的时候平均数是-nan,而交上去AC了的是0,证明可能没有此数据,而且还有考虑精度问题。
代码:
#include<bits/stdc++.h>
double EPS = 1e-5;
using namespace std;
map<string, int>existsid;//Id查找
map<string, vector<int> >existname;//姓名查找
map<int, int>rank1;//存排名
queue<int>already;
struct student
{
int sumscore;
string sid;
int cid;
string name;
int score[4];
friend bool operator <(student x, student y)
{
if (x.sid.length() == y.sid.length())return x.sid<y.sid;
else return x.sid.length()<y.sid.length();
}
friend ostream& operator<<(ostream& cout, student x)
{
cout << x.sid << " " << x.cid << " " << x.name;
for (int i = 0; i<4; i++)
{
cout << " " << x.score[i];
}
printf(" %d %.2lf", x.sumscore, 1.0*x.sumscore / 4);
return cout;
}
}st[205], input, temp;//学生成绩数据
struct ends
{
int sumstudent;
int chpass, enpass, mathpass, programpass;
int sumch, sumen, summath, sumprogram;
int a[5];
ends()
{
sumstudent = chpass = enpass = mathpass = programpass = sumch = sumen = summath = sumprogram = 0;
a[0] = a[1] = a[2] = a[3] = a[4] = 0;
}
}sumend[25];//存3里的输出数据
void title()//每次一开始显示这个
{
cout << "Welcome to Student Performance Management System (SPMS)." << endl;
cout << endl;
cout << "1 - Add" << endl;
cout << "2 - Remove" << endl;
cout << "3 - Query" << endl;
cout << "4 - Show ranking" << endl;
cout << "5 - Show Statistics" << endl;
cout << "0 - Exit" << endl;
cout << endl;
}
void cleardatabase()//清空
{
int i;
while (!already.empty())
{
already.pop();
}
for (i = 1; i <= 200; i++)
{
already.push(i);
}
rank1.clear();
existsid.clear();
existname.clear();
}
void choose1()
{
cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
cin >> input.sid;
if (input.sid == "0")return;
cin >> input.cid >> input.name >> input.score[0] >> input.score[1] >> input.score[2] >> input.score[3];
input.sumscore = input.score[0] + input.score[1] + input.score[2] + input.score[3];
int t = 0;
if (existsid[input.sid])cout << "Duplicated SID." << endl;
else
{
//此处开始存统计数据
rank1[input.sumscore]++;
sumend[0].sumstudent++;
sumend[input.cid].sumstudent++;
sumend[0].sumch += input.score[0];
sumend[input.cid].sumch += input.score[0];
sumend[0].summath += input.score[1];
sumend[input.cid].summath += input.score[1];
sumend[0].sumen += input.score[2];
sumend[input.cid].sumen += input.score[2];
sumend[0].sumprogram += input.score[3];
sumend[input.cid].sumprogram += input.score[3];
if (input.score[0] >= 60)
{
sumend[0].a[++t]++;
sumend[0].chpass++;
sumend[input.cid].a[t]++;
sumend[input.cid].chpass++;
}
if (input.score[1] >= 60)
{
sumend[0].a[++t]++;
sumend[0].mathpass++;
sumend[input.cid].a[t]++;
sumend[input.cid].mathpass++;
}
if (input.score[2] >= 60)
{
sumend[0].a[++t]++;
sumend[0].enpass++;
sumend[input.cid].a[t]++;
sumend[input.cid].enpass++;
}
if (input.score[3] >= 60)
{
sumend[0].a[++t]++;
sumend[0].programpass++;
sumend[input.cid].a[t]++;
sumend[input.cid].programpass++;
}
//统计结束
st[already.front()] = input;
existsid[input.sid] = already.front();
existname[input.name].push_back(already.front());
already.pop();
}
choose1();
}
void choose2()
{
int sums=0;
cout << "Please enter SID or name. Enter 0 to finish." << endl;
cin >> input.sid;
if (input.sid == "0")return;
if (existsid[input.sid])//找到存在ID需要删除
{
//开始统计数据
temp = st[existsid[input.sid]];
sumend[0].sumstudent--;
sumend[temp.cid].sumstudent--;
int t = 0;
sumend[0].sumch -= temp.score[0];
sumend[temp.cid].sumch -= temp.score[0];
sumend[0].summath -= temp.score[1];
sumend[temp.cid].summath -= temp.score[1];
sumend[0].sumen -= temp.score[2];
sumend[temp.cid].sumen -= temp.score[2];
sumend[0].sumprogram -= temp.score[3];
sumend[temp.cid].sumprogram -= temp.score[3];
if (temp.score[0] >= 60)
{
sumend[0].a[++t]--;
sumend[0].chpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].chpass--;
}
if (temp.score[1] >= 60)
{
sumend[0].a[++t]--;
sumend[0].mathpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].mathpass--;
}
if (temp.score[2] >= 60)
{
sumend[0].a[++t]--;
sumend[0].enpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].enpass--;
}
if (temp.score[3] >= 60)
{
sumend[0].a[++t]--;
sumend[0].programpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].programpass--;
}
sums+=1;
already.push(existsid[input.sid]);
rank1[temp.sumscore]--;
//统计结束
existsid[temp.sid] = 0;//删除ID
vector<int>::iterator it;
for(it=existname[temp.name].begin();it!=existname[temp.name].end();it++)//同时找到并删除ID相关的一个姓名
{
if(st[*it].sid==input.sid)break;
}
if(it!=existname[temp.name].end())existname[temp.name].erase(it);
}
if (existname[input.sid].size()>0)//找到姓名需要删除
{
sums+=existname[input.sid].size();
//继续统计数据修改
while (existname[input.sid].size()>0)
{
sumend[0].sumstudent--;
temp = st[existname[input.sid].back()];
sumend[temp.cid].sumstudent--;
int t = 0;
sumend[0].sumch -= temp.score[0];
sumend[temp.cid].sumch -= temp.score[0];
sumend[0].summath -= temp.score[1];
sumend[temp.cid].summath -= temp.score[1];
sumend[0].sumen -= temp.score[2];
sumend[temp.cid].sumen -= temp.score[2];
sumend[0].sumprogram -= temp.score[3];
sumend[temp.cid].sumprogram -= temp.score[3];
if (temp.score[0] >= 60)
{
sumend[0].a[++t]--;
sumend[0].chpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].chpass--;
}
if (temp.score[1] >= 60)
{
sumend[0].a[++t]--;
sumend[0].mathpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].mathpass--;
}
if (temp.score[2] >= 60)
{
sumend[0].a[++t]--;
sumend[0].enpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].enpass--;
}
if (temp.score[3] >= 60)
{
sumend[0].a[++t]--;
sumend[0].programpass--;
sumend[temp.cid].a[t]--;
sumend[temp.cid].programpass--;
}
already.push(existname[input.sid].back());
rank1[temp.sumscore]--;
//结束->此处省略千字(吐血身亡)
existsid[temp.sid]=0;//删ID
existname[temp.name].pop_back();//删姓名
}
}
cout << sums << " student(s) removed." << endl;
choose2();
}
void choose3()
{
map<int, int>::iterator it;
cout << "Please enter SID or name. Enter 0 to finish." << endl;
cin >> input.sid;
if (input.sid == "0")return;
if (existsid[input.sid])//找到ID
{
int ls = 0, flag = 0;
for (it = rank1.begin(); it != rank1.end(); it++)
{
if (it->first == st[existsid[input.sid]].sumscore)
{
flag = 1;
}
else if (flag)
{
ls += it->second;
}
}
cout << ls + 1 << " ";
cout << st[existsid[input.sid]] << endl;
}
else if (existname[input.sid].size()>0)//找到姓名
{
for (int i = 0; i<existname[input.sid].size(); i++)
{
int ls = 0, flag = 0;
for (it = rank1.begin(); it != rank1.end(); it++)
{
if (it->first == st[existname[input.sid][i]].sumscore)
{
flag = 1;
}
else if (flag)
{
ls += it->second;
}
}
cout << ls + 1 << " ";
cout << st[existname[input.sid][i]] << endl;
}
}
choose3();
}
void choose4()
{
cout << "Showing the ranklist hurts students' self-esteem. Don't do that." << endl;
}
void choose5()
{
int cl;
//终于输出数据了
cout << "Please enter class ID, 0 for the whole statistics." << endl;
cin >> cl;
cout << "Chinese" << endl;
cout << "Average Score: "; printf("%.2lf\n", sumend[cl].sumstudent==0?0:sumend[cl].sumch*1.0 / sumend[cl].sumstudent+EPS);
cout << "Number of passed students: " << sumend[cl].chpass << endl;
cout << "Number of failed students: " << sumend[cl].sumstudent - sumend[cl].chpass << endl;
cout << endl;
cout << "Mathematics" << endl;
cout << "Average Score: "; printf("%.2lf\n", sumend[cl].sumstudent==0?0:sumend[cl].summath*1.0 / sumend[cl].sumstudent+EPS);
cout << "Number of passed students: " << sumend[cl].mathpass << endl;
cout << "Number of failed students: " << sumend[cl].sumstudent - sumend[cl].mathpass << endl;
cout << endl;
cout << "English" << endl;
cout << "Average Score: "; printf("%.2lf\n", sumend[cl].sumstudent==0?0:sumend[cl].sumen*1.0 / sumend[cl].sumstudent+EPS);
cout << "Number of passed students: " << sumend[cl].enpass << endl;
cout << "Number of failed students: " << sumend[cl].sumstudent - sumend[cl].enpass << endl;
cout << endl;
cout << "Programming" << endl;
cout << "Average Score: "; printf("%.2lf\n", sumend[cl].sumstudent==0?0:sumend[cl].sumprogram*1.0 / sumend[cl].sumstudent+EPS);
cout << "Number of passed students: " << sumend[cl].programpass << endl;
cout << "Number of failed students: " << sumend[cl].sumstudent - sumend[cl].programpass << endl;
cout << endl;
cout << "Overall:" << endl;
cout << "Number of students who passed all subjects: " << sumend[cl].a[4] << endl;
cout << "Number of students who passed 3 or more subjects: " << sumend[cl].a[3] << endl;
cout << "Number of students who passed 2 or more subjects: " << sumend[cl].a[2] << endl;
cout << "Number of students who passed 1 or more subjects: " << sumend[cl].a[1] << endl;
cout << "Number of students who failed all subjects: " << sumend[cl].sumstudent-sumend[cl].a[1] << endl;
cout << endl;
}
int main()
{
cleardatabase();
int choose;
while (1)
{
title();
cin >> choose;
if (choose == 0)break;
else if (choose == 1)choose1();
else if (choose == 2)choose2();
else if (choose == 3)choose3();
else if (choose == 4)choose4();
else if (choose == 5)choose5();
}
}