万分感谢!
#include <bits/stdc++.h>
#define u(m, s) m*60+s
#define IL inline
using namespace std;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
IL int read()
{
int x = 0,f = 1;
char c = getchar();
while(c <'0'|| c >'9'){if(c == '-') f = -1;c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar();
return x * f;
}
void write(int x)
{
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
long long stod(string strd, string strh) //strd 表示日期字符串 strh 表示hh:mm:ss的时间字符串
//功能为把时间转为时间戳
{
tm tpt;
int y = 2017, mo, d, h, m, s;
mo = ((strd[4] - '0') * 10 + (strd[5] - '0')); //把日期字符串的月份部分提取出并转化为数
d = ((strd[6] - '0') * 10 + (strd[7] - '0')); //把日期字符串的日期部分提取出并转化为数
sscanf(strh.c_str(),"%d:%d:%d", &h, &m, &s); //提取出日期字符串的时、分、秒
//构造时间点类
tpt.tm_year = y-1900;
tpt.tm_mon = mo-1;
tpt.tm_mday = d;
tpt.tm_hour = h;
tpt.tm_min = m;
tpt.tm_sec = s;
tpt.tm_isdst = 0;
time_t scz = mktime(&tpt); //转为时间戳
return scz;
}
struct Record //阳光长跑记录
{
double d; //距离
long long st; //开始时间戳
long long et; //结束时间戳
//平均速度
int zt; //总暂停时间
int zs; //总步数
};
struct Student
{
long long id; //学号
bool sex; //1男0女
int bs; //总成绩
int yg; //阳光长跑合法次数
int bx; //班级训练营
vector <Record> sun; //阳光长跑记录
};
int n, m; //学生个数 + 记录
map <long long, int> mp; //学号 <=> 存储下标
Student a[N]; //学生数组
int GetQMCP(int p, int m, int s)
{
int ty = u(m, s);
if(a[p].sex)
{
//男
if(ty <= u(12, 30)) return 20;
else if(ty <= u(13, 0)) return 18;
else if(ty <= u(13, 30)) return 16;
else if(ty <= u(14, 0)) return 14;
else if(ty <= u(14, 30)) return 12;
else if(ty <= u(15, 10)) return 10;
else if(ty <= u(15, 50)) return 8;
else if(ty <= u(16, 30)) return 6;
else if(ty <= u(17, 10)) return 4;
else if(ty <= u(18, 0))return 2;
else return 0;
}
else
{
//女
if(ty <= u(6, 40)) return 20;
else if(ty <= u(6, 57)) return 18;
else if(ty <= u(7, 14)) return 16;
else if(ty <= u(7, 31)) return 14;
else if(ty <= u(7, 50)) return 12;
else if(ty <= u(8, 5)) return 10;
else if(ty <= u(8, 20)) return 8;
else if(ty <= u(8, 35)) return 6;
else if(ty <= u(8, 50)) return 4;
else if(ty <= u(9, 0)) return 2;
else return 0;
}
}
int GetSLR(int k) //阳光长跑成绩
{
if(k >= 21) return 10;
else if(19 <= k && k <= 20) return 9;
else if(17 <= k && k <= 18) return 8;
else if(14 <= k && k <= 16) return 7;
else if(11 <= k && k <= 13) return 6;
else if(7 <= k && k <= 10) return 4;
else if(3 <= k && k <= 6) return 2;
else return 0;
}
int GetCQC(int k) //出勤次数
{
if(k >= 18) return 5;
else if(15 <= k && k <= 17) return 4;
else if(12 <= k && k <= 14) return 3;
else if(9 <= k && k <= 11) return 2;
else if(6 <= k && k <= 8) return 1;
else return 0;
}
string GetRate(Student x) //根据成绩评等级
{
int u = x.bs;
if(95 <= u && u <= 100) return "A";
else if(90 <= u && u < 95) return "A-";
else if(85 <= u && u < 90) return "B+";
else if(80 <= u && u < 85) return "B";
else if(77 <= u && u < 80) return "B-";
else if(73 <= u && u < 77) return "C+";
else if(70 <= u && u < 73) return "C";
else if(67 <= u && u < 70) return "C-";
else if(63 <= u && u < 67) return "D+";
else if(60 <= u && u < 63) return "D";
else return "F";
}
int main()
{
cin >> n;
for(int i = 1;i <= n;i++)
{
//学号
cin >> a[i].id;
//性别
char t;
cin >> t;
a[i].sex = (t == 'M' ? 1 : 0);
int x, y, z;
cin >> a[i].bs; //专项成绩
scanf("%d\'%d\"", &x, &y);
a[i].bs += GetQMCP(i, x, y); //长跑成绩
cin >> t;
a[i].bs += (t == 'F' ? 0 : 10); //体测
cin >> z;
a[i].bs += z; //期末检测部分
cin >> a[i].bx;
mp[a[i].id] = i; //将学号和存储下标建立对应
//期末长跑 + 体育专项 + 体测 + 大一专项计划的期末检测部分 的成绩(可直接在输入时解决的)
}
//阳光
cin >> m;
for(int i = 1;i <= m;i++)
{
string date;
cin >> date; //日期
long long p;
cin >> p;
int u = mp[p];
string sts, eds;
cin >> sts >> eds; //开始与结束
Record t;
cin >> t.d;
int y, z;
scanf("%d\'%d\"", &y, &z);
t.zt = u(y, z);
cin >> t.zs;
t.st = stod(date, sts); //转化开始时间戳
t.et = stod(date, eds); //转化结束时间戳
a[u].sun.push_back(t);
}
for(int i = 1;i <= n;i++)
{
bool first = 1;
long long lastt = 0;
int cnt = 0;
for(int j = 0;j < a[i].sun.size();j++)
{
Record u = a[i].sun[j];
//男生长跑距离 3000 米以上(包含 3000 米),女生长跑距离 1500 米以上(包含 1500 米);
if((a[i].sex && u.d < 3000) || (!a[i].sex && u.d < 1500)) continue;
//平均速度
// 2 <= d/t <= 3
// !(d/t < 2 || d/t > 3 )
if(u.d < 2 * (u.et - u.st) || u.d > 3 * (u.et - u.st)) continue;
//总暂停时间不得超过 4 分 30 秒
if(u.zt > u(4, 30)) continue;
//平均步幅
//d<=zs*1.5
if(u.d > u.zs * 1.5) continue;
//开始时间需与上条合法记录的结束时间间隔 6 小时以上(包含 6 小时);
if(!first && (u.st - lastt) < 21600) continue;
if(first) first = 0;
lastt = u.et;
cnt++;
}
a[i].yg = cnt;
}
//阳光长跑 + 大一专项出勤次数部分
//首先搞定阳光
for(int i = 1;i <= n;i++) a[i].bs += GetSLR(a[i].yg);
//其次出勤次数
for(int i = 1;i <= n;i++) a[i].bs += GetCQC(a[i].yg + a[i].bx);
//完事!
//按字典序排一下
for(int i = 1; i <= n;i++)
{
cout << a[i].id << ' ' << a[i].bs << ' ';
cout << GetRate(a[i]) << endl;
}
return 0;
}