designed the data structure
This commit is contained in:
95
src/main.cpp
95
src/main.cpp
@ -105,32 +105,68 @@ template<typename A_t,typename B_t,typename C_t,typename D_t> inline void write(
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
static_assert(sizeof(int) == 4, "Expected 32-bit integer.");
|
static_assert(sizeof(int) == 4, "Expect int as a 32-bit integer.");
|
||||||
static_assert(sizeof(long long) == 8, "Expected 64-bit integer.");
|
static_assert(sizeof(long long) == 8, "Expect long long as a 64-bit integer.");
|
||||||
namespace ICPCManager {
|
namespace ICPCManager {
|
||||||
namespace BackEnd {
|
namespace BackEnd {
|
||||||
|
/**
|
||||||
|
* Note that the team id is 1-based. The problem id is 0-based.
|
||||||
|
*/
|
||||||
const int kMaxTeamNumber = 10005;
|
const int kMaxTeamNumber = 10005;
|
||||||
std::unordered_map<std::string, int> team_name_to_id;
|
std::unordered_map<std::string, int> team_name_to_id;
|
||||||
std::vector<std::string> team_id_to_name = {"nobody"};
|
std::vector<std::string> team_id_to_name = {"nobody"};
|
||||||
int team_number = 0;
|
int team_number = 0;
|
||||||
bool competition_on = false;
|
enum CompetitionStatusType { kNotStarted, kNormalRunning, kFrozen, kEnded };
|
||||||
|
enum SubmissionStatusType { kAC = 0, kWA = 1, kRE = 2, kTLE = 3 };
|
||||||
|
CompetitionStatusType competition_status = kNotStarted;
|
||||||
|
bool score_board_up_to_date = true;
|
||||||
|
struct ScoreBoredElementType {
|
||||||
|
int tid;
|
||||||
|
std::string name;
|
||||||
|
int score;
|
||||||
|
int penalty;
|
||||||
|
};
|
||||||
|
inline bool operator<(const ScoreBoredElementType &a,
|
||||||
|
const ScoreBoredElementType &b) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
std::set<ScoreBoredElementType> score_board;
|
||||||
|
/**
|
||||||
|
* @brief the definition of struct RawTeamDataType
|
||||||
|
*
|
||||||
|
* @details it stores the data of a team
|
||||||
|
*/
|
||||||
|
struct RawTeamDataType {
|
||||||
|
std::string name;
|
||||||
|
int id;
|
||||||
|
struct SubmissionType {
|
||||||
|
bool processed = false;
|
||||||
|
SubmissionStatusType status;
|
||||||
|
int submit_time;
|
||||||
|
};
|
||||||
|
int query_status_index[4], query_problem_index[26],
|
||||||
|
query_problem_status_index[26][4];
|
||||||
|
bool is_frozen[26] = {false};
|
||||||
|
std::vector<SubmissionStatusType> submissions;
|
||||||
|
RawTeamDataType() { ; }
|
||||||
|
};
|
||||||
|
std::vector<RawTeamDataType> team_data = {RawTeamDataType()};
|
||||||
/**
|
/**
|
||||||
* @brief the definition of function AddTeam.
|
* @brief the definition of function AddTeam.
|
||||||
* @param team_name the name of the team to be added.
|
* @param team_name the name of the team to be added.
|
||||||
*/
|
*/
|
||||||
void AddTeam(const char *const team_name) {
|
void AddTeam(const char *const team_name) {
|
||||||
/*check if the name is duplicated*/
|
/*check if the name is duplicated*/
|
||||||
if (team_name_to_id.find(team_name) != team_name_to_id.end())
|
if (team_name_to_id.find(team_name) != team_name_to_id.end()) {
|
||||||
{
|
|
||||||
write("[Error]Add failed: duplicated team name.\n");
|
write("[Error]Add failed: duplicated team name.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*check if the competition has started*/
|
/*check if the competition has started*/
|
||||||
if (competition_on)
|
if (competition_status != kNotStarted) {
|
||||||
{
|
|
||||||
write("[Error]Add failed: competition has started.\n");
|
write("[Error]Add failed: competition has started.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -139,7 +175,16 @@ void AddTeam(const char *const team_name) {
|
|||||||
team_id_to_name.push_back(team_name);
|
team_id_to_name.push_back(team_name);
|
||||||
write("[Info]Team added.\n");
|
write("[Info]Team added.\n");
|
||||||
}
|
}
|
||||||
|
inline void FreezeScoreBoard() { competition_status = kFrozen; }
|
||||||
} // namespace BackEnd
|
} // namespace BackEnd
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief the namespace API is used to provide APIs for the main program.
|
||||||
|
*
|
||||||
|
* @details the APIs will call the functions in BackEnd to do the real work.
|
||||||
|
* Then checking for unexpected error will be done here, thus the parameters
|
||||||
|
* given to the functions in BackEnd are always valid.
|
||||||
|
*/
|
||||||
namespace API {
|
namespace API {
|
||||||
/**
|
/**
|
||||||
* @brief this function is used to add a team.
|
* @brief this function is used to add a team.
|
||||||
@ -155,6 +200,10 @@ void AddTeam(const char *const team_name) {
|
|||||||
// All checks passed.
|
// All checks passed.
|
||||||
BackEnd::AddTeam(team_name);
|
BackEnd::AddTeam(team_name);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief the definition of function FreezeScoreBoard
|
||||||
|
*/
|
||||||
|
inline void FreezeScoreBoard() { ICPCManager::BackEnd::FreezeScoreBoard(); }
|
||||||
/**
|
/**
|
||||||
* @brief this function is used to end the contest.
|
* @brief this function is used to end the contest.
|
||||||
*/
|
*/
|
||||||
@ -162,8 +211,12 @@ void EndContest() {
|
|||||||
write("[Info]Competition ends.\n");
|
write("[Info]Competition ends.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
} // namespace API
|
/**
|
||||||
} // namespace ICPCManager
|
* @brief the definition of function Excute.
|
||||||
|
*
|
||||||
|
* @details this function will analyze the command and call the corresponding
|
||||||
|
* function in API.
|
||||||
|
*/
|
||||||
inline void Excute(const char *const command) {
|
inline void Excute(const char *const command) {
|
||||||
char command_name[1024];
|
char command_name[1024];
|
||||||
sscanf(command, "%s", command_name);
|
sscanf(command, "%s", command_name);
|
||||||
@ -172,9 +225,17 @@ inline void Excute(const char *const command) {
|
|||||||
sscanf(command, "%*s%s", team_name);
|
sscanf(command, "%*s%s", team_name);
|
||||||
ICPCManager::API::AddTeam(team_name);
|
ICPCManager::API::AddTeam(team_name);
|
||||||
} else if (strcmp(command_name, "START") == 0) { // start the contest
|
} else if (strcmp(command_name, "START") == 0) { // start the contest
|
||||||
;
|
int duration_time, problem_count, paramater_count;
|
||||||
|
paramater_count =
|
||||||
|
sscanf(command, "%*s%*s%d%*s%d", &duration_time, &problem_count);
|
||||||
|
if (paramater_count != 2) throw "Invalid paramaters.";
|
||||||
} else if (strcmp(command_name, "SUBMIT") == 0) { // submit a code
|
} else if (strcmp(command_name, "SUBMIT") == 0) { // submit a code
|
||||||
;
|
char problem_name;
|
||||||
|
char team_name[100];
|
||||||
|
char submit_status[10];
|
||||||
|
int time;
|
||||||
|
sscanf(command, "%*s%c%*s%s%*s%s%*s%d", &problem_name, team_name,
|
||||||
|
submit_status, &time);
|
||||||
} else if (strcmp(command_name, "FLUSH") == 0) { // flush the
|
} else if (strcmp(command_name, "FLUSH") == 0) { // flush the
|
||||||
;
|
;
|
||||||
} else if (strcmp(command_name, "FREEZE") == 0) {
|
} else if (strcmp(command_name, "FREEZE") == 0) {
|
||||||
@ -182,21 +243,27 @@ inline void Excute(const char *const command) {
|
|||||||
} else if (strcmp(command_name, "SCROLL") == 0) {
|
} else if (strcmp(command_name, "SCROLL") == 0) {
|
||||||
;
|
;
|
||||||
} else if (strcmp(command_name, "QUERY_RANKING") == 0) {
|
} else if (strcmp(command_name, "QUERY_RANKING") == 0) {
|
||||||
;
|
char team_name[100];
|
||||||
|
sscanf(command, "%*s%s", team_name);
|
||||||
} else if (strcmp(command_name, "QUERY_SUBMISSION") == 0) {
|
} else if (strcmp(command_name, "QUERY_SUBMISSION") == 0) {
|
||||||
;
|
char team_name[100];
|
||||||
|
char problem_name;
|
||||||
|
char status[10];
|
||||||
|
sscanf(command, "%*s%s%*s%*s%c%*s%*s%s", team_name, &problem_name, status);
|
||||||
} else if (strcmp(command_name, "END") == 0) // END
|
} else if (strcmp(command_name, "END") == 0) // END
|
||||||
{
|
{
|
||||||
ICPCManager::API::EndContest();
|
ICPCManager::API::EndContest();
|
||||||
} else
|
} else
|
||||||
throw "Unknown command.";
|
throw "Unknown command.";
|
||||||
}
|
}
|
||||||
|
} // namespace API
|
||||||
|
} // namespace ICPCManager
|
||||||
int main() {
|
int main() {
|
||||||
char command[1024];
|
char command[1024];
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
readline(command);
|
readline(command);
|
||||||
Excute(command);
|
ICPCManager::API::Excute(command);
|
||||||
}
|
}
|
||||||
} catch (const char *msg) {
|
} catch (const char *msg) {
|
||||||
fprintf(stderr, "\e[7m\e[31m[Unexpected Error] %s\e[0m\n", msg);
|
fprintf(stderr, "\e[7m\e[31m[Unexpected Error] %s\e[0m\n", msg);
|
||||||
|
Reference in New Issue
Block a user