體育成績統計/ Score
阿新 • • 發佈:2020-11-27
> 偏水向,請部分學術控諒解
題目過長,不再描述。
很顯然就是一道大模擬對吧,我在這裡貢獻一下我打此題的思路與過程。
或許有些奇淫巧技可以供一些沒有過掉的神犇借鑑一下。
#### 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$。
帶著看看能拿多少分的心態,交了一發。
後面的事情大家都知道了。
***
#### 具體實現
寫的略有點冗長,僅供參考,輕噴。
```cpp
#include
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 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;
}
```