考察:考场内排序,考场外又排序一次,两次排序
learn && wrong:
1、考场号置为i就行了,而不是人数,第二个输入数字是人数,你搞错了
2、结构体名字跟结构体数组名字冲突了,cmp做参数就不知道哪一个了
3、sort函数可以对二维数组用行排列
4、得出序号,第一个设置序号设置为1,借来for循环,如果相同,则与前一个相同,不同则下标+1
5、结构体不设排序号,直接输出排序号,就是设一个变量+一个循环
id(i > 0 && stu[i].score != stu[i - 1].score){
r = i + 1;
}
//pritnf之类或者stu[i].r = r;
6、这招不错,顶一个int型变量,没读入一个考生,就让num自增,当读取完一个考场的考生信息,(假设该考场有k个考生)后,这个考场的考生所对应的数组下标区间为【num - k,num)
输入:
1、考场数
2、考场人数
3、考生号+分数(13位+0~100分
考场小于100个,每个考场小于300人
输出:
registration_number final_rank location_number local_rank
以分数排序,如果分数相同,则考生号以字典序小的排序
同样分数同样内的排名
编程思想:
1、结构体数组:准考证,分数,考场号,考场内的排名,总排名,30010个,
输入考场号,然后输入每个考场内考生,注意把结构体数组标记考场号
然后排序考场内的
2、
再排序总的,然后输出总的,输出各项数据
注意:因为二维数组不知道如何给序号,所以整个复制过来再排序
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct student{
char id[15];//考生号
int score; //分数
int test_location;//考场号
int local_rank; //考场内排名
int final_rank; //总排名
}stu[101][301], stu1[30001]; //前面考场号,后面考生号比较好!
bool cmp(student a, student b) { //比较函数,按分数排名,如果相同,则按字典序从大到小 (!!!)名词跟数组名字冲突了
if (a.score != b.score) return a.score > b.score;
else return strcmp(a.id, b.id) < 0;
}
int main()
{
int total;
cin >> total; //几个考场
//int sum = 0; 统计总人数
int sum[101];//累计总人数数组
for (int i = 0;i < total;++i) { //(!!!)太笨了,用一个循环啊!
int local;
cin >> local; //人数
//sum += local; 每次输入人数还要累加总人数,不能这么做,用一个数组来把每个考场的人数添加进来
sum[i] = local;
for (int j = 0;j < local;++j) {
cin >> stu[i][j].id >> stu[i][j].score; //输入id和分数
stu[i][j].test_location = i + 1; //修改考场号
}
sort(stu[i], stu[i] + local, cmp);//考场内排序 (!!!)应该可以的
stu[i][0].local_rank = 1; //(!!!)得出考场内排名,注意,排序跟得出序号是完全不一样的
for (int k = 1;k < local;k++) {
//(!!!)得出排名的第一步,一定要弄第一个为1,然后k = 1开始
if (stu[i][k].score == stu[i][k - 1].score) {
stu[i][k].local_rank = stu[i][k - 1].local_rank;
}
else {
stu[i][k].local_rank = k + 1; //(!!!)注意是k + 1;
}
}
}
int sum1 = 0;
for (int i = 0;i < total;i++){ //累计总人数
sum1 += sum[i];
}
//总排名的排序来一次,仍旧是,然后排名怎么弄,算了我直接再开一个数组好了,然后复制过来...
/* 这个排序是错的!
sort(student, student + sum1;cmp); //总的排序
student[0][0].final_rank = 1;
int z = 0;
for (int j = 1;j < sum[j];++j) { //(!!!)新花样,双重数组的排名,有点区别,应该让第一排单独一个循环,然后之后就是双重循环了
if (student[z][j] == student[z][j - 1]) {
student[z][j].final_rank = student[z].final_rank;
}else{
student[z][j].final_rank = j + 1;
}
}
++z;
for (; z < total;z++) { //(!!!)总的排序我不会。。。、
for(int j = 0;)
}
*/
int num = 0; //整个复制过来,并且总人数也知道了
for (int i = 0;i < total;++i) {
for (int j = 0;j < sum[i];++j) {
stu1[num++] = stu[i][j];
}
}
printf("%d\n", num); //输出人数
sort(stu1, stu1 + num,cmp);
int r = 1;
for (int i = 0;i < num;i++) { //(!!!)不修改排名直接输出,也不错
if (i > 0 && stu1[i].score != stu1[i - 1].score) {
r = i + 1; //当前考生与上一个考生分数不同时,让r更新为人数+1
}
printf("%s ", stu1[i].id);
printf("%d %d %d\n", r, stu1[i].test_location, stu1[i].local_rank);
}
return 0;
}