class Student
{
public:
long long sid;
int cid;
string name;
int k[4], total = 0;
double avg;
void create(long long sid, int cid, string name, int k1, int k2, int k3, int k4)
{
this->sid = sid, this->cid = cid, this->name = name;
this->k[0] = k1, this->k[1] = k2, this->k[2] = k3, this->k[3] = k4;
total += k1 + k2 + k3 + k4, avg = 0.25 * (k1 + k2 + k3 + k4) + eps;
}
int get_rank() // 对于一个学生,求它的排名
{
int p = 1, tmp = 0;
for (int i = 400; i > total; i--)
{
if (rk[i])
tmp += rk[i]; // 并列的加一起
else
p += tmp, tmp = 0;
}
return p + tmp;
}
};
void add_oper()
{
long long sid;
int cid, k1, k2, k3, k4, id;
string name;
while (true)
{
printf("Please enter the SID, CID, name and four scores. Enter 0 to finish.\n");
cin >> sid;
if (!sid)
return;
cin >> cid >> name >> k1 >> k2 >> k3 >> k4;
if (SID[sid])
cout << "Duplicated SID.\n";
else
{
SID[sid] = true, id = name2id(name);
Student now;
now.create(sid, cid, name, k1, k2, k3, k4);
sname[id].push_back(now), stu.push_back(now); // 为名字对应的集合sname添加,总集合stu添加
room[cid].stu.push_back(now), Stu[sid] = now; // 为cid班级的学生集合添加,建立sid与Student映射
rk[now.total]++; // 标记存在的学生
}
}
}
void remove_oper() // 删除学生信息
{
long long sid;
string name;
int id, sum; // sum记录一共删除了几个
while (true)
{
printf("Please enter SID or name. Enter 0 to finish.\n"), sum = 0;
cin >> name;
if (name[0] >= '0' && name[0] <= '9') // 判断是sid还是name
{
sid = to_num(name); // 转为正常的long long类型的sid,方便建立映射
if (!sid)
return;
else if (SID[sid])
SID[sid] = false, sum++, rk[Stu[sid].total]--; // 标记false意味着删除了
}
else
{
id = name2id(name); // 通过name获得名字id,然后访问名字id对应的学生集合
for (int i = 0; i < sname[id].size(); i++)
if (SID[sname[id][i].sid]) // 对该集合没被删除的学生标记false并统计删除人数
SID[sname[id][i].sid] = false, rk[Stu[sid].total]--, sum++;
}
printf("%d student(s) removed.\n", sum);
}
}
获得rank排名这一步错了,排名总是偏高,由于我判断学生是否存在是通过SID来判断(类似标记数组),删除了我就标记为false,添加了我就标记为true。但是我想知道,我每次插入新同学都会rk【total】++把成绩加上,每次删除同学都会rk【total】--把成绩减下去,这对应的操作为什么会导致排名偏高