G must be rounded up to an integer 向上取整:四舍五入
1.10 不懂呃,我们是通过名字来找到结构体的,所以在赋值的时候一定要输入结构体的名字
map[s].id = s; //之前没有写这一步,没有id,就找不到这个结构体
map[s].gp = grade;
初始化可以构建一个初始化函数
struct{
void calc()
{
if (fin >= mid) total = fin;
else total = round(mid*0.4 + fin*0.6);
}
};
if (!map.count(s)) map[s].init();
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
using namespace std;
const int N = 10010;
int n, m, k; //gp,mid,final
struct Student
{
string id;
int gp, mid, fin, total;
//Student() : gp(-1), mid(-1), fin(-1), total(0){} //默认构造
void init()
{
gp = mid = fin = -1;
total = 0;
}
void calc()
{
if (fin >= mid) total = fin;
else total = round(mid*0.4 + fin*0.6);
}
bool has_pass()
{
if (gp < 200 || total < 60) return false;
return true;
}
bool operator < (const Student& t)
{
if (total != t.total) return total > t.total;
return id < t.id;
}
};
unordered_map<string, Student> map;
vector<Student> res; //可以输出的节点
int main()
{
scanf("%d%d%d", &n, &m, &k);
char op[25];
string s;
int grade;
for (int i = 0; i < n; i++)
{
scanf("%s%d", op, &grade);
s = op;
if (!map.count(s)) map[s].init();
map[s].id = s; //之前没有写这一步,没有id,就找不到这个结构体
map[s].gp = grade;
}
for (int i = 0; i < m; i++)
{
scanf("%s%d", op, &grade);
s = op;
if (!map.count(s)) map[s].init();
map[s].id = s;
map[s].mid = grade;
}
for (int i = 0; i < k; i++)
{
scanf("%s%d", op, &grade);
s = op;
if (!map.count(s)) map[s].init();
map[s].id = s;
map[s].fin = grade;
}
for (auto& item : map)
{
auto& c = item.second;
c.calc();
if (c.has_pass())
res.push_back(c);
}
sort(res.begin(), res.end());
for (auto& c : res)
printf("%s %d %d %d %d\n", c.id.c_str(), c.gp, c.mid, c.fin, c.total);
return 0;
}
https://www.acwing.com/solution/content/143343/
1561. PAT 评测(结构体内部构造函数)(unordered_map<string,Student)(扫描指针找排名)
思路:
因为有分别多次输入同一个名字的线上,期中,期末成绩,所以不能直接在结构体内部中初始化
,必须要重构
(类似java思想),然后在内部也构建一个计算总成绩的函数,再在结构体内部重载小于号
,有多个关键字。
要快速知道现在这个名字的所有信息,所以要建立<unordered_map>
将名字与结构体映射起来
重构
重构是隐藏的,在生成这个结构体的时候,若它还没有生成结构体成员,就会默认调用重构函数,所以无需自己调用
struct Node
{
string name;
int grade;
Node() : grade(0) //grade 初始化为0
{
}
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <cmath>
using namespace std;
struct Student
{
string name;
int p, mid_g, final_g, grade; //grade:总成绩
//将线上,期中,期末的成绩都初始化为-1,
//重构函数,创建一个结构体的时候就默认调用
Student() : p(-1), mid_g(-1), final_g(-1), grade(0){}
//计算总成绩
void calc()
{
if (final_g >= mid_g) grade = final_g;
else grade = round(mid_g*0.4 + final_g*0.6);
}
//排序,重载小于号
bool operator < (const Student& t)
{
if (grade != t.grade) //第一关键字:按总成绩降序
return grade > t.grade;
else //第二关键字:按名字升序
return name < t.name;
}
}student;
int main()
{
int p, m, n; //线上,期中,期末的人数
cin >> p >> m >> n;
unordered_map<string, Student> map; //建立名字与结构体的映射关系,可以直接查找到名字
string name;
int x;
//线上
for (int i = 0; i < p; i++)
{
cin >> name >> x;
map[name].name = name;
map[name].p = x;
}
//期中
for (int i = 0; i < m; i++)
{
cin >> name >> x;
map[name].name = name;
map[name].mid_g = x;
}
//期末
for (int i = 0; i < n; i++)
{
cin >> name >> x;
map[name].name = name;
map[name].final_g = x;
}
//将符合条件的人加到答案中
vector<Student> res;
for (auto item : map)
{
auto stu = item.second; //stu:结构体
stu.calc();
if (stu.p >= 200 && stu.grade >= 60)
res.push_back(stu);
}
//排序
sort(res.begin(), res.end());
//输出
for (auto c : res)
{
cout << c.name << ' ' << c.p << ' '<< c.mid_g;
cout << ' ' << c.final_g << ' ' << c.grade << endl;
}
return 0;
}