一定一定要把一些重复的东西打包成数组,这样不容易出错。
总结一下一些前人的经验吧。
不保证阳光长跑相邻两条的时间不相交(如果你是所有的转换为秒数后在做不需要注意这一条)
注意很多很多的“不超过”“不慢于”“不快于”等判断时候等号是否取到(我自己发现的)
浮点数大小判断有没有+eps,所有都要用(这一方面,如果你开了double,一般没什么问题了,一定要注意少用a-1.5<0来判断,更加保险的可以化除为乘)
结束时间减开始时间,而不是开始时间减结束时间
长度单位转换好了吗?
阳光长跑保证不会横跨多天。
sort 不稳定!sort 不稳定!sort 不稳定!排序不能只按照日期排!要排多关键字!要不然有可能本机 AC 提交暴零!
检查存每个学生上条合法记录的时间是否记录的是结束时间,而非开始时间。
开始时间需与上条合法记录的结束时间间隔 6 小时以上(包含 6 小时);
注意,是合法记录!
顺便给出我的代码(可读性极强):
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MT int TTT=R;while(TTT--)
#define pc putchar
#define R read()
#define fo(i,a,b) for(register int i=a;i<=b;i++)
#define rep(i,a,b) for(register int i=a;i>=b;i--)
#define m1(a,b) memset(a,b,sizeof a)
int read()
{
int x=0;
char ch=getchar();
bool f=0;
while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(f) x=-x;
return x;
}
template<typename T> inline void write(T x)
{
if(x<0)
{
pc('-');
x=-x;
}
if(x>9) write(x/10);
pc(x%10+'0');
}
const int N=1.5e5+10;
int day_in_month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int boy_run[]={750,780,810,840,870,910,950,990,1030,1080};
int girl_run[]={400,417,434,451,470,485,500,515,530,540};
int trans(int month,int date,int h,int m,int s)
{
int day=date-1;
fo(i,1,month-1) day+=day_in_month[i];
return (day*24+(h-1))*3600+(m-1)*60+s;
}
int tran(int m,int s)
{
return m*60+s;
}
int n,m;
struct Stu
{
int girl_boy;
int grade_can_calc;
int last_run,run_times,yangguang_times;
};
map<int,Stu> ma;
// struct Run
// {
// int month,date;
// int number;
// int st,ed;
// double dist;
// int stopm,stops;
// int pace_num;
// }r[N];
int calc_run_grade(int x)
{
if(x>=18) return 5;
if(x>=15) return 4;
if(x>=12) return 3;
if(x>=9) return 2;
if(x>=6) return 1;
return 0;
}
int calc_yangguang_grade(int x)
{
if(x>=21) return 10;
if(x>=19) return 9;
if(x>=17) return 8;
if(x>=14) return 7;
if(x>=11) return 6;
if(x>=7) return 4;
if(x>=3) return 2;
return 0;
}
signed main(){
n=R;
fo(C,1,n)
{
int num=R;
char c=getchar();
while(c!='M'&&c!='F') c=getchar();
ma[num].girl_boy=(c=='M'?1:2);
int s=R;
ma[num].grade_can_calc+=s;
int min,sec;
scanf("%lld'%lld\"",&min,&sec);
int tt=tran(min,sec);
if(c=='M'){fo(i,0,9) if(tt<=boy_run[i]){ma[num].grade_can_calc+=20-i*2;break;}}
else{fo(i,0,9) if(tt<=girl_run[i]){ma[num].grade_can_calc+=20-i*2;break;}}
c=getchar();
while(c!='P'&&c!='F') c=getchar();
if(c=='P') ma[num].grade_can_calc+=10;
ma[num].grade_can_calc+=R;
ma[num].run_times+=R;
ma[num].last_run=-2e9;
}
m=R;
fo(C,1,m)
{
int TT=R;
TT=TT%10000;
int month=TT/100,date=TT%100;
int num=R;
int sth,stm,sts,edh,edm,eds;
scanf("%lld:%lld:%lld %lld:%lld:%lld",&sth,&stm,&sts,&edh,&edm,&eds);
int st=trans(month,date,sth,stm,sts),ed=trans(month,date,edh,edm,eds);
double dist;
cin>>dist;
dist*=1000;
int min,sec;
scanf("%lld'%lld\"",&min,&sec);
int stop_time=tran(min,sec);
int bushu=R;
bool is_ans=1;
int girl_boy=ma[num].girl_boy;
if(girl_boy==1)
{
if(dist<3000) is_ans=0;
}
else
{
if(dist<1500) is_ans=0;
}
if(dist/(ed-st)<2||dist/(ed-st)>5) is_ans=0;
if(stop_time>270) is_ans=0;
if(dist/bushu>1.5) is_ans=0;
if(st-ma[num].last_run<21600) is_ans=0;
if(is_ans) ma[num].last_run=ed;
ma[num].run_times+=is_ans;
ma[num].yangguang_times+=is_ans;
}
for(auto i:ma)
{
write(i.first),pc(' ');
int grade=calc_yangguang_grade(i.second.yangguang_times)+calc_run_grade(i.second.run_times)+i.second.grade_can_calc;
write(grade),pc(' ');
if(grade>=95) puts("A");
else if(grade>=90) puts("A-");
else if(grade>=85) puts("B+");
else if(grade>=80) puts("B");
else if(grade>=77) puts("B-");
else if(grade>=73) puts("C+");
else if(grade>=70) puts("C");
else if(grade>=67) puts("C-");
else if(grade>=63) puts("D+");
else if(grade>=60) puts("D");
else puts("F");
}
}