浅谈online judge平台 spj [special judge] 使用 | 修改问题(下)

简介: 第六种:交互题的spj第七种[带有testlib.h]的另一种解决方式第八种 使用validation.h的BAPC2018(较难)

第六种:交互题的spj


本平台暂不支持交互题,所以题库里的交互题目前没有进行处理通过

可以参考 洛谷的交互题spj 对应写法


第七种[带有testlib.h]的另一种解决方式


…遇见后后续更新

2021-10-21更新

将以下文件入口对应

inf->标准输入 argv[1]

ouf->用户输出 argv[3]

ans->答案结果 argv[2]


void registerTestlibCmd(int argc, char* argv[]) {
  __testlib_ensuresPreconditions();
  testlibMode = _checker;
  __testlib_set_binary(stdin);
  if (argc > 1 && !strcmp("--help", argv[1]))
    __testlib_help();
  // if (argc < 4 || argc > 6)
  // {
  //     quit(_fail, std::string("Program must be run with the following arguments: ") +
  //         std::string("<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]") +
  //         "\nUse \"--help\" to get help information");
  // }
  appesMode = false;
//  if (argc == 3) {///改 
//    resultName = "";
//    appesMode = false;
//  }
//
//  if (argc == 4) {
//    resultName = make_new_file_in_a_dir(argv[3]);
//    appesMode = false;
//  }///改 
  // if (argc == 6)
  // {
  //     if (strcmp("-APPES", argv[5]) && strcmp("-appes", argv[5]))
  //     {
  //         quit(_fail, std::string("Program must be run with the following arguments: ") +
  //                     "<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]");
  //     }
  //     else
  //     {
  //         resultName = argv[4];
  //         appesMode = true;
  //     }
  // }
  inf.init(argv[1], _input);
  ouf.init(argv[3], _output);
  ans.init(argv[2], _answer);/// 改 
}
void registerTestlib(int argc, ...) {
  if (argc  < 3 || argc > 5)
    quit(_fail, std::string("Program must be run with the following arguments: ") +
         "<input-file> <output-file> <answer-file> [<report-file> [<-appes>]]");
  char** argv = new char*[argc + 1];
  va_list ap;
  va_start(ap, argc);
  argv[0] = NULL;
  for (int i = 0; i < argc; i++) {
    argv[i + 1] = va_arg(ap, char*);
  }
  va_end(ap);
  registerTestlibCmd(argc + 1, argv);
  delete[] argv;
}


第八种 使用validation.h的BAPC2018(较难)


首先站是原始的BAPC后台validation.h文件:

// A header library to safely parse team input.
// It does not support floating points or big integers.
// The easiest way to use this is to symlink it from a validator directory,
// so that it will be picked up when creating a contest zip.
// The default checking behaviour is lenient for both white space and case.
// When validating .in and .ans files, the case_sensitve and space_change_sensitive flags should be
// passed. When validating team output, the flags in problem.yaml should be used.
#include <algorithm>
#include <stdexcept>
#include <fstream>
#include <iostream>
#include <limits>
using namespace std;
const string case_sensitive_flag         = "case_sensitive";
const string space_change_sensitive_flag = "space_change_sensitive";
class Validator {
  const int ret_AC = 42, ret_WA = 43;
  bool case_sensitive;
  bool ws;
  public:
  Validator(int argc, char **argv, istream &in = std::cin) : in(in) {
    for(int i = 0; i < argc; ++i) {
      if(argv[i] == case_sensitive_flag) case_sensitive = true;
      if(argv[i] == space_change_sensitive_flag) ws = true;
    }
    if(ws) in >> noskipws;
  }
  // No copying, no moving.
  Validator(const Validator &) = delete;
  Validator(Validator &&)      = delete;
  // At the end of the scope, check whether the EOF has been reached.
  // If so, return AC. Otherwise, return WA.
  ~Validator() {
    eof();
    AC();
  }
  void space() {
    if(ws) {
      char c;
      in >> c;
      if(c != ' ') expected("space", string("\"") + c + "\"");
    }
    // cerr << "read space!\n";
  }
  void newline() {
    if(ws) {
      char c;
      in >> c;
      if(c != '\n') expected("newline", string("\"") + c + "\"");
    }
    // cerr << "read newline!\n";
  }
  // Just read a string.
  string read_string() { return read_string_impl(); }
  // Read a string and make sure it equals `expected`.
  string read_string(string expected) { return read_string_impl(expected); }
  // Read an arbitrary string of a given length.
  string read_string(size_t min, size_t max) {
    string s = read_string();
    if(s.size() < min || s.size() > max)
      expected("String of length between " + to_string(min) + " and " + to_string(max), s);
    return s;
  }
  // Read the string t.
  void test_string(string t) {
    string s = read_string();
    if(case_sensitive) {
      if(s != t) expected(t, s);
    } else {
      if(lowercase(s) != lowercase(t)) expected(t, s);
    }
  }
  // Read a long long.
  long long read_long_long() {
    string s = read_string_impl("", "integer");
    long long v;
    try {
      size_t chars_processed = 0;
      v                      = stoll(s, &chars_processed);
      if(chars_processed != s.size())
        WA("Parsing " + s + " as long long failed! Did not process all characters");
    } catch(const out_of_range &e) {
      WA("Number " + s + " does not fit in a long long!");
    } catch(const invalid_argument &e) { WA("Parsing " + s + " as long long failed!"); }
    return v;
  }
  // Read a long long within a given range.
  long long read_long_long(long long low, long long high) {
    auto v = read_long_long();
    if(low <= v && v <= high) return v;
    expected("integer between " + to_string(low) + " and " + to_string(high), to_string(v));
  }
  int read_int() {
    return read_long_long(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
  }
  int read_int(int low, int high) {
    int v = read_long_long(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
    if(low <= v && v <= high) return v;
    expected("integer between " + to_string(low) + " and " + to_string(high), to_string(v));
  }
  // Read a long double.
  long double read_long_double() {
    string s = read_string_impl("", "integer");
    long double v;
    try {
      size_t chars_processed;
      v = stold(s, &chars_processed);
      if(chars_processed != s.size())
        WA("Parsing ", s, " as long double failed! Did not process all characters.");
    } catch(const out_of_range &e) {
      WA("Number " + s + " does not fit in a long double!");
    } catch(const invalid_argument &e) { WA("Parsing " + s + " as long double failed!"); }
    return v;
  }
  // Check the next character.
  bool peek(char c) {
    if(!ws) in >> ::ws;
    return in.peek() == char_traits<char>::to_int_type(c);
  }
  // Return WRONG ANSWER verdict.
  [[noreturn]] void expected(string exp = "", string s = "") {
    if(s.size())
      cout << "Expected " << exp << ", found " << s << endl;
    else if(exp.size())
      cout << exp << endl;
    exit(ret_WA);
  }
  template <typename T>
  [[noreturn]] void WA(T t) {
    cout << t << endl;
    exit(ret_WA);
  }
  template <typename T, typename... Ts>
  [[noreturn]] void WA(T t, Ts... ts) {
    cout << t;
    WA(ts...);
  }
  template <typename... Ts>
  void assert(bool b, Ts... ts) {
    if(!b) WA(ts...);
  }
  private:
  // Read an arbitrary string.
  // expected: if not "", string must equal this.
  // wanted: on failure, print "expected <wanted>, got ..."
  string read_string_impl(string expected_string = "", string wanted = "string") {
    if(ws) {
      char next = in.peek();
      if(isspace(next)) expected(wanted, "whitespace");
    }
    string s;
    if(in >> s) {
      if(!case_sensitive) {
        s               = lowercase(s);
        expected_string = lowercase(expected_string);
      }
      if(!expected_string.empty() && s != expected_string)
        WA("Expected string \"expected\", but found ", s);
      return s;
    }
    expected(wanted, "nothing");
  }
  // Return ACCEPTED verdict.
  [[noreturn]] void AC() { exit(ret_AC); }
  void eof() {
    if(in.eof()) return;
    // Sometimes EOF hasn't been triggered yet.
    if(!ws) in >> ::ws;
    char c = in.get();
    if(c == char_traits<char>::eof()) return;
    expected("EOF", string("\"") + char(c) + "\"");
  }
  // Convert a string to lowercase is matching is not case sensitive.
  string &lowercase(string &s) {
    if(!case_sensitive) return s;
    transform(s.begin(), s.end(), s.begin(), ::tolower);
    return s;
  }
  istream &in;
};


我们尤其需要注意公有成员方法:

Validator(int argc, char **argv, istream &in = std::cin) : in(in) {
    for(int i = 0; i < argc; ++i) {
      if(argv[i] == case_sensitive_flag) case_sensitive = true;
      if(argv[i] == space_change_sensitive_flag) ws = true;
    }
    if(ws) in >> noskipws;
  }


main中的前几行代码:

// Set up the input and answer streams.
  std::ifstream in(argv[1]);
  std::ifstream ans(argv[2]);


因为本平台都是使用文件的形式进行判断所提交的代码,这里可以用流的形式进行操作,将42、43改成对应的0、1然后将main中添加如下代码:

// Set up the input and answer streams.
  std::ifstream in(argv[1]);
  std::ifstream ans(argv[2]);
  std::ifstream user(argv[3]);
  Validator out(argc, argv, user);
  // 以下代码为输入


然后将公有成员构造方法改成:

Validator(int argc, char **argv, std::ifstream &in) : in(in) {
  for(int i = 0; i < argc; ++i) {
    if(argv[i] == case_sensitive_flag) case_sensitive = true;
    if(argv[i] == space_change_sensitive_flag) ws = true;
  }
  if(ws) in >> noskipws;
}


即可完美解决

目录
相关文章
Operator ‘==‘ cannot be applied to ‘int‘, ‘null‘
Operator ‘==‘ cannot be applied to ‘int‘, ‘null‘
|
索引
LeetCode 287. Find the Duplicate Number
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
86 0
LeetCode 287. Find the Duplicate Number
|
Python
【hacker的错误集】TypeError: can‘t multiply sequence by non-int of type ‘str‘
我比较喜欢通过单词的意思来分析报错 TypeError类型错误 multiply乘 sequence 序列 通过分析可以得出报错意思大概是类型错误:无法将序列与字符串类型的非整数相乘
365 0
【hacker的错误集】TypeError: can‘t multiply sequence by non-int of type ‘str‘
|
Java Linux C++
浅谈online judge平台 spj [special judge] 使用 | 修改问题(上)
浅谈oj平台 spj 使用 | 修改问题 首先: 参数对应 返回值 代码提交 几种spj 第一种:简单的一类特判 第二种:多组输入的特判 第三种:需要判断特殊情况[impossible] 第四种:带有[testlib.h]的spj 第五种:GCPC [German Collegiate Programming Contest] 类spj
578 0
浅谈online judge平台 spj [special judge] 使用 | 修改问题(上)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
112 0
|
C++
PAT (Advanced Level) Practice - 1038 Recover the Smallest Number(30 分)
PAT (Advanced Level) Practice - 1038 Recover the Smallest Number(30 分)
123 0
|
编译器 Linux C语言
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction
763 0
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction