diff --git a/web/app/controllers/new_remote_problem.php b/web/app/controllers/new_remote_problem.php
index d76aecd..7fb3e9a 100644
--- a/web/app/controllers/new_remote_problem.php
+++ b/web/app/controllers/new_remote_problem.php
@@ -107,6 +107,7 @@ $new_remote_problem_form->runAtServer();
目前支持导入以下题库的题目作为远端评测题:
- Codeforces
+ - Codeforces::Gym(题号前加
GYM
)
在导入题目前请先搜索题库中是否已经存在相应题目,避免重复添加。
diff --git a/web/app/libs/uoj-validate-lib.php b/web/app/libs/uoj-validate-lib.php
index adea031..426cc92 100644
--- a/web/app/libs/uoj-validate-lib.php
+++ b/web/app/libs/uoj-validate-lib.php
@@ -77,5 +77,5 @@ function is_short_string($str) {
}
function validateCodeforcesProblemId($str) {
- return preg_match('/[1-9][0-9]{0,5}[A-Z][1-9]?/', $str) !== true;
+ return preg_match('/(|GYM)[1-9][0-9]{0,5}[A-Z][1-9]?/', $str) !== true;
}
diff --git a/web/app/models/UOJRemoteProblem.php b/web/app/models/UOJRemoteProblem.php
index 6074faa..e152893 100644
--- a/web/app/models/UOJRemoteProblem.php
+++ b/web/app/models/UOJRemoteProblem.php
@@ -16,28 +16,16 @@ class UOJRemoteProblem {
];
static function getCodeforcesProblemUrl($id) {
+ if (str_starts_with($id, 'GYM')) {
+ return static::$providers['codeforces']['url'] . '/gym/' . preg_replace_callback('/GYM([1-9][0-9]{0,5})([A-Z][1-9]?)/', fn ($matches) => $matches[1] . '/problem/' . $matches[2], $id);
+ }
+
return static::$providers['codeforces']['url'] . '/problemset/problem/' . preg_replace_callback('/([1-9][0-9]{0,5})([A-Z][1-9]?)/', fn ($matches) => $matches[1] . '/' . $matches[2], $id);
}
- // 传入 ID 需确保有效
- static function getCodeforcesProblemBasicInfo($id) {
- $curl = new Curl();
- $curl->setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 S2OJ/3.1.0');
-
+ static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
$remote_provider = static::$providers['codeforces'];
- $html = retry_loop(function () use ($curl, $id) {
- $curl->get(static::getCodeforcesProblemUrl($id));
-
- if ($curl->error) {
- return false;
- }
-
- return $curl->response;
- });
-
- if (!$html) return null;
-
$html = preg_replace('/\$\$\$/', '$', $html);
$dom = new \IvoPetkov\HTML5DOMDocument();
$dom->loadHTML($html);
@@ -51,8 +39,9 @@ class UOJRemoteProblem {
}
$statement_dom = $dom->querySelector('.problem-statement');
+ $title_prefix = str_starts_with($id, 'GYM') ? '' : 'CF';
$title = explode('. ', trim($statement_dom->querySelector('.title')->innerHTML))[1];
- $title = "【{$remote_provider['short_name']}{$id}】{$title}";
+ $title = "【{$title_prefix}{$id}】{$title}";
$time_limit = intval(substr($statement_dom->querySelector('.time-limit')->innerHTML, 53));
$memory_limit = intval(substr($statement_dom->querySelector('.memory-limit')->innerHTML, 55));
$difficulty = -1;
@@ -120,6 +109,7 @@ class UOJRemoteProblem {
}
return [
+ 'type' => 'html',
'title' => $title,
'time_limit' => $time_limit,
'memory_limit' => $memory_limit,
@@ -128,6 +118,52 @@ class UOJRemoteProblem {
];
}
+ // 传入 ID 需确保有效
+ static function getCodeforcesProblemBasicInfo($id) {
+ $curl = new Curl();
+ $curl->setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 S2OJ/3.1.0');
+
+ $res = retry_loop(function () use (&$curl, $id) {
+ $curl->get(static::getCodeforcesProblemUrl($id));
+
+ if ($curl->error) {
+ return false;
+ }
+
+ return [
+ 'content-type' => $curl->response_headers['Content-Type'],
+ 'response' => $curl->response,
+ ];
+ });
+
+ if (!$res) return null;
+
+ if (str_starts_with($res['content-type'], 'text/html')) {
+ return static::getCodeforcesProblemBasicInfoFromHtml($id, $res['response']);
+ } else if (str_starts_with($res['content-type'], 'application/pdf')) {
+ $title_prefix = str_starts_with($id, 'GYM') ? '' : 'CF';
+ $title = "【{$title_prefix}{$id}】{$title_prefix}{$id}";
+
+ return [
+ 'type' => 'pdf',
+ 'title' => $title,
+ 'time_limit' => null,
+ 'memory_limit' => null,
+ 'difficulty' => -1,
+ 'statement' => HTML::tag('h3', [], '提示') .
+ HTML::tag(
+ 'p',
+ [],
+ '本题题面为 PDF 题面,请' .
+ HTML::tag('a', ['href' => static::getCodeforcesProblemUrl($id), 'target' => '_blank'], '点此') .
+ '以查看题面。'
+ ),
+ ];
+ } else {
+ return null;
+ }
+ }
+
public static function getProblemRemoteUrl($oj, $id) {
if ($oj === 'codeforces') {
return static::getCodeforcesProblemUrl($id);