体育成绩统计/ Score
偏水向,请部分学术控谅解
题目过长,不再描述。
很显然就是一道大模拟对吧,我在这里贡献一下我打此题的思路与过程。
或许有些奇淫巧技可以供一些没有过掉的神犇借鉴一下。
2020.11.26
中午: 昨天GM开的最后一题好像还没做?去看看去看看。
花了接近一个中午,整理出了大纲,然后调了一下输入。
一些规定
1. 体育课专项成绩:直接给出,总分 \(50pt\)。
2. 长跑测试成绩:根据表格完成,总分 \(20pt\)。
3. 阳光长跑:
3.1 合法次数标准:
-
条件1:男生长跑距离 \(\geq 3000\),女生长跑距离 \(\geq 1500\)。
-
条件2:平均速度 \(v\),\(2m/s \leq v \leq 5m/s\)。
-
条件3:总暂停时间 \(bt\),\(bt \leq 4.5min\)。
-
条件4:距离/步数 \(sv\),\(sv \leq 1.5m\)。
-
条件5:开始时间 \(st\),\(gap(last, st) \geq 6h\)。
3.2 根据表格完成,总分 \(10pt\)。
3.3 特殊的,对于条件5,需要考虑跨天,跨月,跨分钟,跨小时。
4. 体质测试:通过,满分 \(10pt\);不通过,\(0pt\)。
5. 大一专项计划:
5.1 班级训练营 \(c\) + 阳光长跑合法次数 \(q\)。根据表格完成, 总分 \(5pt\)。
5.2 期末检测直接给出,总分 \(5pt\)。
变量含义
data:
\(stu\) :学生信息。
\(sun\):阳光长跑信息。
\(node\):开始时间:小时,分钟,秒。
int:
\(n\) :学生人数。
\(stu.s\):体育专项成绩。
\(stu.f\):「大一专项计划」的期末检测成绩。
\(stu.c\) :参加「班级训练营」的次数。
\(m\) :需要筛选的「阳光长跑」数据条数
\(sun.num\):学号对应学生编号。
\(sun.st\):开始时间(\(node\)
\(sun.ed\):结束时间(\(node\)
\(sun.t\):持续时间。
\(sun.dist\):距离。
\(sun.v\):平均速度,\(v=dist / t\)。
\(sun.bt\):暂停时间,以秒为单位。
\(sun.step\):运动步数。
\(sun.sv\):步幅。
\(stu.time\):期末长跑成绩(秒为单位。
\(stu.ans\):最终成绩。
\(stu.pass\):合格次数。
char:
\(stu.sex\):性别。(M为男生,F为女生。
\(stu.phy\):是否通过体质测试。(\(P\) 为过,\(F\) 为不过。
\(sun.date\):时间。
long long
\(stu.p\):学号。
map
\(index\):根据学号求下标。
晚上(睡觉前): 这道题或许需要一个优秀的算法去判断两条阳光长跑信息的时间差。(即条件5的处理。
好像起始时间减去上一条的结束时间不好算。
因为要考虑月,天,时,秒。
那要不就直接将上一条的信息加上6小时,再比较当前时间的大小?
这样感觉就好实现一点了,模拟一个类高精加。
如果超过时间限制,就当前位减,下一位加。比如,如果 \(h \geq 24\),则 \(h = h – 24\),\(day = day + 1\)。
2020.11.27
中午:
开始实现。
利用整理出来的大纲进行操作。
先从小的开始,比如那些输入完就会直接产生价值的数据。
然后做稍微难一点的,比如那些要很多个选择结构才能产生价值的数据。
最后维护最难的,如此题中的阳光长跑信息。对于难一点的,要先分条,理清思路再维护。
耗了一个中午初稿完成。不过被GM友情资助的大数据卡死了。
在睡觉时间结束后调试,发现自己没加阳光长跑版块与加上后输出答案一样。
那肯定就是阳光长跑版块的问题咯。不过中午被赶下去上WHK了。
晚上:
尝试调试。
从阳光长跑信息的输入开始看。
断点输出了几组后,诶,这不就出问题了嘛。错因:在运算中,把输入的表示长跑距离的 \(dx\),写成了前面用于输入日期的 \(x\)。
带着看看能拿多少分的心态,交了一发。
后面的事情大家都知道了。
具体实现
写的略有点冗长,仅供参考,轻喷。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int read() {
int k = 1, x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
}
LL read_LL() {
int k = 1;
LL x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
}
int read_time() {
char s = getchar();
while (s < '0' || s > '9')
s = getchar();
int M = 0;
while (s >= '0' && s <= '9') {
M = (M << 3) + (M << 1) + (s ^ 48);
s = getchar();
}
while (s < '0' || s > '9')
s = getchar();
int S = 0;
while (s >= '0' && s <= '9') {
S = (S << 3) + (S << 1) + (s ^ 48);
s = getchar();
}
return M * 60 + S;
}
const int MAXN = 4 * 1e3 + 5;
const int MAXM = 1e5 + 5 * 1e4 + 5;
struct node {
int h, m, s;
node() {}
node(int H, int M, int S) {
h = H;
m = M;
s = S;
}
void Read() {
char c = getchar();
while(c < '0' || c > '9')
c = getchar();
while(c >= '0' && c <= '9') {
h = (h << 3) + (h << 1) + (c ^ 48);
c = getchar();
}
while(c < '0' || c > '9')
c = getchar();
while(c >= '0' && c <= '9') {
m = (m << 3) + (m << 1) + (c ^ 48);
c = getchar();
}
while(c < '0' || c > '9')
c = getchar();
while(c >= '0' && c <= '9') {
s = (s << 3) + (s << 1) + (c ^ 48);
c = getchar();
}
}
};
struct Date {
int year, month, day;
Date() {}
Date(int Y, int M, int D) {
year = Y;
month = M;
day = D;
}
};
struct Stu {
LL p;
int s, f, c, time, ans, pass;
char sex[5], phy[5];
Stu() {
ans = 0;
}
} stu[MAXN];
struct Sun {
node st, ed;
int t, dist, v, bt, step, sv, num;
Date date;
} sun[MAXM];
void check_2(int i) { // 2
if(stu[i].sex[0] == 'M') {
if(stu[i].time <= 12 * 60 + 30)
stu[i].ans += 20;
else if(stu[i].time <= 13 * 60)
stu[i].ans += 18;
else if(stu[i].time <= 13 * 60 + 30)
stu[i].ans += 16;
else if(stu[i].time <= 14 * 60)
stu[i].ans += 14;
else if(stu[i].time <= 14 * 60 + 30)
stu[i].ans += 12;
else if(stu[i].time <= 15 * 60 + 10)
stu[i].ans += 10;
else if(stu[i].time <= 15 * 60 + 50)
stu[i].ans += 8;
else if(stu[i].time <= 16 * 60 + 30)
stu[i].ans += 6;
else if(stu[i].time <= 17 * 60 + 10)
stu[i].ans += 4;
else if(stu[i].time <= 18 * 60)
stu[i].ans += 2;
}
else {
if(stu[i].time <= 6 * 60 + 40)
stu[i].ans += 20;
else if(stu[i].time <= 6 * 60 + 57)
stu[i].ans += 18;
else if(stu[i].time <= 7 * 60 + 14)
stu[i].ans += 16;
else if(stu[i].time <= 7 * 60 + 31)
stu[i].ans += 14;
else if(stu[i].time <= 7 * 60 + 50)
stu[i].ans += 12;
else if(stu[i].time <= 8 * 60 + 5)
stu[i].ans += 10;
else if(stu[i].time <= 8 * 60 + 20)
stu[i].ans += 8;
else if(stu[i].time <= 8 * 60 + 35)
stu[i].ans += 6;
else if(stu[i].time <= 8 * 60 + 50)
stu[i].ans += 4;
else if(stu[i].time <= 9 * 60)
stu[i].ans += 2;
}
}
int Mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int last[MAXN];
bool check_3(int x) {
int p = sun[x].num;
if((stu[p].sex[0] == 'F' && sun[x].dist < 1500)
|| (stu[p].sex[0] == 'M' && sun[x].dist < 3000))
return false;
// 条件 1
LL St = sun[x].st.h * 3600 + sun[x].st.m * 60 + sun[x].st.s;
LL Ed = sun[x].ed.h * 3600 + sun[x].ed.m * 60 + sun[x].ed.s;
LL down = 2 * (Ed - St), Up = 5 * (Ed - St);
if(sun[x].dist < down || sun[x].dist > Up)
return false;
// 条件 2
if(sun[x].bt > 270)
return false;
// 条件 3
if(2 * sun[x].dist > 3 * sun[x].step)
return false;
// 条件 4
int Last = last[p];
Date D = sun[Last].date;
node T = sun[Last].ed;
T.h += 6;
if(T.h >= 24) {
D.day++;
T.h -= 24;
}
if(D.day > Mon[D.month]) {
D.month++;
D.day -= Mon[D.month];
}
if(D.month > sun[x].date.month)
return false;
else if(D.month == sun[x].date.month) {
if(D.day > sun[x].date.day)
return false;
else if(D.day == sun[x].date.day) {
if(T.h > sun[x].st.h)
return false;
else if(T.h == sun[x].st.h) {
if(T.m > sun[x].st.m)
return false;
else if(T.m == sun[x].st.m && T.s > sun[x].st.s)
return false;
}
}
}
// 条件 5
last[p] = x;
return true;
}
void check_sun(int i) {
if(stu[i].pass >= 21)
stu[i].ans += 10;
else if(stu[i].pass >= 19)
stu[i].ans += 9;
else if(stu[i].pass >= 17)
stu[i].ans += 8;
else if(stu[i].pass >= 14)
stu[i].ans += 7;
else if(stu[i].pass >= 11)
stu[i].ans += 6;
else if(stu[i].pass >= 7)
stu[i].ans += 4;
else if(stu[i].pass >= 3)
stu[i].ans += 2;
}
void check_get(int i) {
int x = stu[i].c + stu[i].pass;
if(x >= 18)
stu[i].ans += 5;
else if(x >= 15)
stu[i].ans += 4;
else if(x >= 12)
stu[i].ans += 3;
else if(x >= 9)
stu[i].ans += 2;
else if(x >= 6)
stu[i].ans += 1;
}
void check_ans(int x) {
if(x >= 95)
printf("A\n");
else if(x >= 90)
printf("A-\n");
else if(x >= 85)
printf("B+\n");
else if(x >= 80)
printf("B\n");
else if(x >= 77)
printf("B-\n");
else if(x >= 73)
printf("C+\n");
else if(x >= 70)
printf("C\n");
else if(x >= 67)
printf("C-\n");
else if(x >= 63)
printf("D+\n");
else if(x >= 60)
printf("D\n");
else
printf("F\n");
}
int n;
map<LL, int> Index;
int main() {
// freopen("1.in", "r", stdin);
// freopen("1.out", "w", stdout);
n = read();
for(int i = 1; i <= n; i++) {
stu[i].p = read_LL();
Index[stu[i].p] = i;
scanf ("%s", stu[i].sex);
stu[i].s = read();
stu[i].ans += stu[i].s; // 1
stu[i].time = read_time();
check_2(i); // 2
scanf ("%s", stu[i].phy);
if(stu[i].phy[0] == 'P') // 4
stu[i].ans += 10;
stu[i].f = read();
stu[i].ans += stu[i].f; // 5.1
stu[i].c = read();
}
int m = read();
for(int i = 1; i <= m; i++) {
int x = read();
sun[i].date.year = 2017;
sun[i].date.day = x % 10 + (x / 10 % 10) * 10;
x /= 100;
sun[i].date.month = x % 10 + (x / 10 % 10) * 10;
LL t = read_LL();
sun[i].num = Index[t];
sun[i].st.Read();
sun[i].ed.Read();
double dx;
scanf ("%lf", &dx);
sun[i].dist = dx * 1000;
sun[i].bt = read_time();
sun[i].step = read();
if(check_3(i)) // 3
stu[sun[i].num].pass++;
}
for(int i = 1; i <= n; i++) {
check_sun(i); // 3
check_get(i); // 5.2
}
for(int i = 1; i <= n; i++) {
printf("%lld %d ", stu[i].p, stu[i].ans);
check_ans(stu[i].ans);
}
return 0;
}