浅谈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;
}


即可完美解决

目录
相关文章
|
2月前
|
编译器 C语言
成功解决“Run-Time Check Failure #2 - Stack around the variable ‘arr‘ was corrupted.“问题
成功解决“Run-Time Check Failure #2 - Stack around the variable ‘arr‘ was corrupted.“问题
105 1
|
Python
【hacker的错误集】TypeError: can‘t multiply sequence by non-int of type ‘str‘
我比较喜欢通过单词的意思来分析报错 TypeError类型错误 multiply乘 sequence 序列 通过分析可以得出报错意思大概是类型错误:无法将序列与字符串类型的非整数相乘
330 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
546 0
浅谈online judge平台 spj [special judge] 使用 | 修改问题(上)
|
安全 iOS开发 MacOS
“XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
“XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
491 0
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
97 0
|
C++
PAT (Advanced Level) Practice - 1038 Recover the Smallest Number(30 分)
PAT (Advanced Level) Practice - 1038 Recover the Smallest Number(30 分)
105 0
uva 10706 - Number Sequence
点击打开链接uva 10706 题目意思:    有一个数组 s[1] = 1 , s[2] = 1 2 , .......s[k] = 1....k,要求给定一个n表示数组的第几位,要求这个第几位是什么数。
929 1
|
SQL Oracle 关系型数据库
Online Data Files move
online data files move,move online,
1661 0