中科大oj 1201 GPA

时间:2019-02-16
本文章向大家介绍中科大oj 1201 GPA,主要包括中科大oj 1201 GPA使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
//为了尽可能提高效率
//使用c语言输入输出,并且使用c字符串和内联函数
//将学生和课程进行编号和排序,通过二分搜索来查找
//再分别同数组存储分数,学分,总分,平均分等信息
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

class Unite{//将字符串编号
public:
  char* str;//字符串
  int id;//相应的编号
};
int n, m, q;
Unite *stu_id[501], *cou_id[501];
inline int stu_getid(char*);//获得学生id
inline int cou_getid(char*);//获得课程id
bool compare(Unite*, Unite*);//比较函数,用于排序
double gpa[101]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1.3, 1.3, 1.3, 1.5, 1.7, 1.7, 1.7, 2, 2, 2, 2, 2.3, 2.3, 2.3, 2.7, 2.7, 2.7, 3, 3, 3, 3, 3.3, 3.3, 3.3, 3.7, 3.7, 3.7, 3.7, 3.7, 4, 4, 4, 4, 4, 4.3, 4.3, 4.3, 4.3, 4.3, 4.3};
//开一个101大小的数组,存储每个分数对应的gpa
int main(){
  scanf("%d%d%d", &n, &m, &q);
  double total_credit[n];//总学分
  double ave_grade[n];//总成绩
  double ave_gpa[n];//总gpa
  for(int i = 0; i < n; i++){//初始化学生信息
    total_credit[i] = 0.0;
    ave_grade[i] = 0.0;
    ave_gpa[i] = 0.0;
    char* id = new char[11];
    scanf("%s", id);
    stu_id[i] = new Unite;
    stu_id[i]->str = id;
    stu_id[i]->id = i;
  }
  sort(stu_id, stu_id + n, compare);//排序
  double total_stu[m];//总学生数
  double credit[m];//课程对应学分
  double total_grade[m];//总分数
  for(int i = 0; i < m; i++){//初始化课程信息
    total_stu[i] = 0;
    total_grade[i] = 0;
    char* id = new char[11];
    double c;
    scanf("%s%lf", id, &c);
    cou_id[i] = new Unite;
    cou_id[i]->str = id;
    cou_id[i]->id = i;
    credit[i] = c;
  }
  sort(cou_id, cou_id + m, compare);//排序
  double score[n][m];
  for(int i = 0; i < n; i++){
    for(int j = 0; j < m; j++){
      score[i][j] = 0;
    }
  }
  for(int i = 0; i < q; i++){//查找
    char choice[11];
    scanf("%s", choice);
    if(strcmp(choice, "score") == 0){
      char id_1[11], id_2[11];
      double grade;
      scanf("%s%s%lf", id_1, id_2, &grade);
      int num_1 = stu_getid(id_1);
      int num_2 = cou_getid(id_2);
      score[num_1][num_2] = grade;
      total_credit[num_1] += credit[num_2];
      ave_grade[num_1] += grade * credit[num_2];
      ave_gpa[num_1] += gpa[(int)grade] * credit[num_2];
      total_grade[num_2] += grade;
      total_stu[num_2]++;
    }else if(strcmp(choice, "student") == 0){
      char id[11];
      scanf("%s", id);
      int ID = stu_getid(id);
      double num_1 = total_credit[ID] == 0 ? 0 : ave_grade[ID] / total_credit[ID];
      double num_2 = total_credit[ID] == 0 ? 0 : ave_gpa[ID] / total_credit[ID];
      printf("%.2lf %.2lf\n", num_1, num_2);
    }else if(strcmp(choice, "course") == 0){
      char id[11];
      scanf("%s", id);
      int ID = cou_getid(id);
      double num = total_stu[ID] == 0 ? 0 : total_grade[ID] / total_stu[ID];
      printf("%.2lf\n", num);
    }else{
      char id_1[11], id_2[11];
      scanf("%s%s", id_1, id_2);
      int ID_1 = stu_getid(id_1);
      int ID_2 = cou_getid(id_2);
      printf("%.0lf %.2lf\n", score[ID_1][ID_2], gpa[(int)score[ID_1][ID_2]]);
    }
  }
  return 0;
}

inline int stu_getid(char* str){//二分查找
  int left = 0;
  int right = n - 1;
  while(left <= right){
    int mid = left + ((right - left) >> 1);
    if (strcmp(str, stu_id[mid]->str) < 0) right = mid - 1;
    else if (strcmp(str, stu_id[mid]->str) > 0) left = mid + 1;
    else return stu_id[mid]->id;
  }
  return -1;
}

inline int cou_getid(char* str){//二分查找
  int left = 0;
  int right = n - 1;
  while(left <= right){
    int mid = left + ((right - left) >> 1);
    if (strcmp(str, cou_id[mid]->str) < 0) right = mid - 1;
    else if (strcmp(str, cou_id[mid]->str) > 0) left = mid + 1;
    else return cou_id[mid]->id;
  }
  return -1;
}

bool compare(Unite* u_1, Unite* u_2){
  return strcmp(u_1->str, u_2->str) < 0;//strcmp是可以按照字典序排序的
}