求调,悬5RMB,有注释
查看原帖
求调,悬5RMB,有注释
430133
liangbob楼主2023/12/6 17:02

万分感谢!

#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;
}
2023/12/6 17:02
加载中...