public static int Check(Answer thisAnswer, Problem thisProblem) { string stdData = thisProblem.StandardOutput.Replace("\r", ""); string data = thisAnswer.OutputData.Replace("\r", ""); string stdDataNp = stdData.Replace("\n", "").Replace("\t", "").Replace(" ", ""); string dataNp = data.Replace("\n", "").Replace("\t", "").Replace(" ", ""); if (stdData.Length < data.Length / 2) { StatusCode = Const.StatusCodeOutputLimitExceeded; } else if (stdData == data) { StatusCode = Const.StatusCodeAccepted; } else if (stdDataNp == dataNp) { StatusCode = Const.StatusCodePresentationError; } else { StatusCode = Const.StatusCodeWrongAnswer; } return StatusCode; }
public static Problem GetProblemById(Int64 id) { var command = TheMySqlConnection.CreateCommand(); command.CommandText = "SELECT `problem`.* FROM `problem` WHERE `problem`.ID = @ID"; command.Parameters.AddWithValue("@ID", id); if (TheMySqlConnection.State == ConnectionState.Closed) TheMySqlConnection.Open(); var thisMySqlDataReader = command.ExecuteReader(); Problem thisProblem = null; try { while (thisMySqlDataReader.Read()) { thisProblem = new Problem( thisMySqlDataReader.GetInt64("ID"), thisMySqlDataReader.GetInt64("TimeLimitNormal"), thisMySqlDataReader.GetInt64("TimeLimitJava"), thisMySqlDataReader.GetInt64("MemoryLimitNormal"), thisMySqlDataReader.GetInt64("MemoryLimitJava"), thisMySqlDataReader.GetString("StandardInput"), thisMySqlDataReader.GetString("StandardOutput") ); } } catch (MySqlConversionException) { throw; } catch (Exception) { throw; } finally { thisMySqlDataReader.Close(); } return thisProblem; }
public static void Run(string workingDirectory, Answer thatAnswer, Problem thatProblem) { StatusCode = Const.StatusCodeAccepted; OutputStringBuilder = new StringBuilder(); ErrorStringBuilder = new StringBuilder(); OutputLimit = thatProblem.StandardOutput.Length * 2; ThatProgramProcess = new Process { StartInfo = { CreateNoWindow = true, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true } }; switch (thatAnswer.LanguageCode) { case Const.LanguageCodeC: case Const.LanguageCodeCpp: ThatProgramProcess.StartInfo.FileName = workingDirectory + "Main.exe"; TimeLimit = thatProblem.TimeLimitNormal; MemoryLimit = thatProblem.MemoryLimitNormal * 1000; break; case Const.LanguageCodeJava: ThatProgramProcess.StartInfo.FileName = "java"; ThatProgramProcess.StartInfo.Arguments = "-cp " + workingDirectory + " " + "Main"; TimeLimit = thatProblem.TimeLimitJava * 1000; MemoryLimit = thatProblem.MemoryLimitJava * 1000; break; default: throw new Exception("不支持的语言类型"); } try { //启动进程 ThatProgramProcess.Start(); //启动时间内存监控线程 var threadWatchTimeAndMemory = new Thread(WatchTimeAndMemory); threadWatchTimeAndMemory.Start(); //启动输出流监控线程 var threadWatchOutputStream = new Thread(WatchOutputStream); threadWatchOutputStream.Start(); //启动错误流监控线程 var threadWatchErrorStream = new Thread(WatchErrorStream); threadWatchErrorStream.Start(); //设置最大使用内存 if (ThatProgramProcess.MaxWorkingSet.ToInt64() < MemoryLimit) ThatProgramProcess.MaxWorkingSet = new IntPtr(MemoryLimit); else throw new OutOfMemoryException(); //输入数据 ThatProgramProcess.StandardInput.Write(thatProblem.StandardInput); ThatProgramProcess.StandardInput.Close(); //等待进程结束 ThatProgramProcess.WaitForExit(); } catch (OutOfMemoryException) { StatusCode = Const.StatusCodeMemoryLimitExceeded; } catch (IOException) { } catch (Exception) { StatusCode = Const.StatusCodeSystemError; } finally { //强制结束进程 try { ThatProgramProcess.Kill(); } catch (Exception) { } switch (StatusCode) { case Const.StatusCodeAccepted: if (ThatProgramProcess.ExitCode != 0) { StatusCode = Const.StatusCodeRuntimeError; Info = ExitCodeDictionary.ContainsKey(ThatProgramProcess.ExitCode) ? ExitCodeDictionary[ThatProgramProcess.ExitCode] : ErrorStringBuilder.ToString(); } else if (ErrorStringBuilder.ToString() != "") { StatusCode = Const.StatusCodeRuntimeError; Info = ErrorStringBuilder.ToString(); } break; case Const.StatusCodeMemoryLimitExceeded: UsedMemory = MemoryLimit; Info = ""; break; case Const.StatusCodeTimeLimitExceeded: UsedTime = TimeLimit; Info = ""; break; case Const.StatusCodeOutputLimitExceeded: Info = ""; break; default: throw new Exception("状态码错误"); } } }