mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-25 21:58:41 +00:00
feat(web/problem/manage/statement): allow select tags to fill
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
ee0ff210bb
commit
8417f362e8
@ -174,6 +174,85 @@ $difficulty_form->runAtServer();
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
<div class="card-header fw-bold">
|
||||
标签填充
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<script>
|
||||
function fillTag(tags) {
|
||||
if (typeof tags === 'string') tags = [tags];
|
||||
|
||||
tags = tags.map(tag => tag.trim()).filter(Boolean);
|
||||
|
||||
var originalTags = $('#input-problem_tags')
|
||||
.val()
|
||||
.replace(/,/g, ',')
|
||||
.split(',')
|
||||
.map(tag => tag.trim())
|
||||
.filter(Boolean);
|
||||
var newTagsSet = new Set(originalTags.concat(tags));
|
||||
|
||||
$('#input-problem_tags').val(Array.from(newTagsSet.values()).join(', '));
|
||||
$('#input-problem_tags').trigger('input');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="row row-cols-4 row-cols-lg-2 g-2">
|
||||
<?php foreach (UOJProblem::$categories as $category => $tags) : ?>
|
||||
<?php $category_id = uniqid('category-'); ?>
|
||||
|
||||
<div class="d-inline-block" id="category-container-<?= $category_id ?>">
|
||||
<button id="category-button-<?= $category_id ?>" class="btn btn-sm btn-light w-100" type="button"><?= $category ?></button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
bootstrap.Popover.jQueryInterface.call($('#category-button-<?= $category_id ?>'), {
|
||||
container: $('#category-container-<?= $category_id ?>'),
|
||||
html: true,
|
||||
placement: 'left',
|
||||
animation: false,
|
||||
trigger: 'manual',
|
||||
fallbackPlacements: ['bottom', 'right'],
|
||||
content: [
|
||||
<?php foreach ($tags as $tag) : ?> '<?= $tag ?>', <?php endforeach ?>
|
||||
].map(tag => ('<button class="btn btn-sm btn-light d-inline-block mr-1 mb-1" onclick="fillTag([\'<?= $category ?>\', \'' + tag + '\'])">' + tag + '</button>')).join(' '),
|
||||
sanitizeFn(content) {
|
||||
return content;
|
||||
},
|
||||
}).on("mouseenter", function() {
|
||||
var _this = this;
|
||||
|
||||
$(this).popover("show");
|
||||
$(this).siblings(".popover").on("mouseleave", function() {
|
||||
$(_this).popover('hide');
|
||||
});
|
||||
}).on("mouseleave", function() {
|
||||
var _this = this;
|
||||
|
||||
var check_popover_status = function() {
|
||||
setTimeout(function() {
|
||||
if (!$(".popover:hover").length) {
|
||||
$(_this).popover("hide")
|
||||
} else {
|
||||
check_popover_status();
|
||||
}
|
||||
}, 50);
|
||||
};
|
||||
|
||||
check_popover_status();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-muted small bg-transparent">
|
||||
将鼠标悬浮至主分类上,点击弹出框中的对应标签即可将其填充至题目标签中。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
<div class="card-header fw-bold">
|
||||
题目难度
|
||||
@ -183,7 +262,6 @@ $difficulty_form->runAtServer();
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
</div>
|
||||
|
||||
<?php echoUOJPageFooter() ?>
|
||||
|
@ -52,6 +52,246 @@ class UOJProblem {
|
||||
3500 => '#aa0000',
|
||||
];
|
||||
|
||||
public static array $categories = [
|
||||
'算法基础' => [
|
||||
'暴力',
|
||||
'枚举',
|
||||
'模拟',
|
||||
'递归与分治',
|
||||
'贪心',
|
||||
'排序',
|
||||
'前缀和与差分',
|
||||
'二分',
|
||||
'倍增',
|
||||
'构造',
|
||||
'打表',
|
||||
],
|
||||
'搜索' => [
|
||||
'深度优先搜索',
|
||||
'广度优先搜索',
|
||||
'双向搜索',
|
||||
'启发式搜索',
|
||||
'A*',
|
||||
'IDA*',
|
||||
'迭代加深',
|
||||
'回溯法',
|
||||
'Dancing Links',
|
||||
],
|
||||
'动态规划' => [
|
||||
'记忆化搜索',
|
||||
'线性 DP',
|
||||
'背包 DP',
|
||||
'区间 DP',
|
||||
'树形 DP',
|
||||
'状压 DP',
|
||||
'数位 DP',
|
||||
'DAG 上 DP',
|
||||
'插头 DP',
|
||||
'概率 DP',
|
||||
'单调队列优化 DP',
|
||||
'斜率优化 DP',
|
||||
'四边形不等式优化 DP',
|
||||
],
|
||||
'计算几何' => [
|
||||
'Pick 定理',
|
||||
'三角剖分',
|
||||
'凸包',
|
||||
'扫描线',
|
||||
'旋转卡壳',
|
||||
'半平面交',
|
||||
'平面最近点对',
|
||||
'随机增量法',
|
||||
'反演变换',
|
||||
],
|
||||
'数学' => [
|
||||
'位运算',
|
||||
'快速幂',
|
||||
'高精度',
|
||||
'生成函数',
|
||||
'指数生成函数',
|
||||
'向量',
|
||||
'矩阵',
|
||||
'高斯消元',
|
||||
'线性基',
|
||||
'线性规划',
|
||||
'容斥',
|
||||
'组合计数',
|
||||
'离散对数',
|
||||
'单纯形算法',
|
||||
'概率',
|
||||
'置换群',
|
||||
'斐波那契数列',
|
||||
'牛顿迭代法',
|
||||
'数值积分',
|
||||
'分块打表',
|
||||
],
|
||||
'数论' => [
|
||||
'最大公约数',
|
||||
'分解质因数',
|
||||
'欧拉函数',
|
||||
'筛法',
|
||||
'欧拉定理',
|
||||
'费马小定理',
|
||||
'类欧几里得算法',
|
||||
'翡蜀定理',
|
||||
'乘法逆元',
|
||||
'线性同余方程',
|
||||
'Meissel-Lehmer 算法',
|
||||
'二次剩余',
|
||||
'BSGS',
|
||||
'原根',
|
||||
'卢卡斯定理',
|
||||
'莫比乌斯反演',
|
||||
'拉格朗日反演',
|
||||
'杜教筛',
|
||||
'Powerful Number 筛',
|
||||
'Min_25 筛',
|
||||
'洲阁筛',
|
||||
'连分数',
|
||||
'Stern-Brocot 数与 Farey 序列',
|
||||
'Pell 方程',
|
||||
],
|
||||
'字符串' => [
|
||||
'字符串哈希',
|
||||
'字典树',
|
||||
'KMP',
|
||||
'Boyer-Moore',
|
||||
'Z 函数(扩展 KMP)',
|
||||
'AC 自动机',
|
||||
'后缀数组',
|
||||
'后缀自动机',
|
||||
'后缀平衡树',
|
||||
'广义后缀自动机',
|
||||
'Manacher',
|
||||
'回文树',
|
||||
'序列自动机',
|
||||
'最小表示法',
|
||||
'Lyndon 分解',
|
||||
],
|
||||
'图论' => [
|
||||
'拓扑排序',
|
||||
'最短路',
|
||||
'K 短路',
|
||||
'同余最短路',
|
||||
'虚树',
|
||||
'树分治',
|
||||
'动态树分治',
|
||||
'树哈希',
|
||||
'树上启发式合并',
|
||||
'AHU 算法',
|
||||
'矩阵树定理',
|
||||
'最小生成树',
|
||||
'最小树形图',
|
||||
'最小直径生成树',
|
||||
'斯坦纳树',
|
||||
'拆点',
|
||||
'差分约束',
|
||||
'强连通分量',
|
||||
'双连通分量',
|
||||
'割点与桥',
|
||||
'圆方树',
|
||||
'2-SAT',
|
||||
'欧拉图',
|
||||
'哈密顿图',
|
||||
'最小环',
|
||||
'平面图',
|
||||
'网络流',
|
||||
'最大流',
|
||||
'最小割',
|
||||
'费用流',
|
||||
'上下界网络流',
|
||||
'Stoer-Wagner 算法',
|
||||
'二分图',
|
||||
'二分图最大匹配',
|
||||
'二分图最大权匹配',
|
||||
'一般图最大匹配',
|
||||
'一般图最大权匹配',
|
||||
'Prufer 序列',
|
||||
'LGV 引理',
|
||||
'弦图',
|
||||
],
|
||||
'组合数学' => [
|
||||
'排列组合',
|
||||
'卡特兰数',
|
||||
'斯特林数',
|
||||
'贝尔数',
|
||||
'伯努利数',
|
||||
'康托展开',
|
||||
'容斥原理',
|
||||
'抽屉原理',
|
||||
'欧拉数',
|
||||
],
|
||||
'数据结构' => [
|
||||
'栈',
|
||||
'队列',
|
||||
'链表',
|
||||
'哈希表',
|
||||
'并查集',
|
||||
'二叉堆',
|
||||
'配对堆',
|
||||
'树状数组',
|
||||
'线段树',
|
||||
'平衡树',
|
||||
'左偏树',
|
||||
'块状数组',
|
||||
'块状链表',
|
||||
'树分块',
|
||||
'Sqrt Tree',
|
||||
'可持久化数据结构',
|
||||
'单调栈',
|
||||
'单调队列',
|
||||
'ST 表',
|
||||
'树套树',
|
||||
'李超线段树',
|
||||
'区间最值操作与区间历史最值',
|
||||
'划分树',
|
||||
'跳表',
|
||||
'K-D Tree',
|
||||
'珂朵莉树',
|
||||
'动态树',
|
||||
'析合树',
|
||||
],
|
||||
'多项式' => [
|
||||
'拉格朗日插值',
|
||||
'快速傅里叶变换',
|
||||
'快速数论变换',
|
||||
'快速沃尔什变换',
|
||||
'多项式求逆',
|
||||
'多项式开方',
|
||||
'多项式除法与取模',
|
||||
'多项式对数函数与指数函数',
|
||||
'多项式牛顿迭代',
|
||||
'多项式多点求值与快速插值',
|
||||
'多项式三角函数',
|
||||
'多项式反三角函数',
|
||||
'常系数齐次线性递推',
|
||||
],
|
||||
'博弈论' => [
|
||||
'不平等博弈',
|
||||
'SG 函数',
|
||||
'Nim 游戏',
|
||||
'Anti-Nim',
|
||||
'纳什均衡',
|
||||
],
|
||||
'杂项' => [
|
||||
'构造',
|
||||
'离散化',
|
||||
'CDQ 分治',
|
||||
'整体二分',
|
||||
'分块',
|
||||
'莫队',
|
||||
'分数规划',
|
||||
'随机化',
|
||||
'模拟退火',
|
||||
'爬山法',
|
||||
'悬线法',
|
||||
'编译原理',
|
||||
'复杂度分析',
|
||||
'语义分析',
|
||||
'底层优化',
|
||||
],
|
||||
];
|
||||
|
||||
public static function query($id) {
|
||||
if (!isset($id) || !validateUInt($id)) {
|
||||
return null;
|
||||
|
@ -1109,6 +1109,11 @@ $(document).ready(function() {
|
||||
[...document.querySelectorAll('[data-bs-toggle="tooltip"]')].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
|
||||
});
|
||||
|
||||
// Popovers
|
||||
$(document).ready(function() {
|
||||
[...document.querySelectorAll('[data-bs-toggle="popover"]')].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
|
||||
});
|
||||
|
||||
// Copy button
|
||||
$(document).ready(function() {
|
||||
$('.markdown-body pre, .copy-button-container pre').each(function () {
|
||||
|
Loading…
Reference in New Issue
Block a user