mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-22 14:48: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>
|
</ul>
|
||||||
</div>
|
</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 mt-3">
|
||||||
<div class="card-header fw-bold">
|
<div class="card-header fw-bold">
|
||||||
题目难度
|
题目难度
|
||||||
@ -183,7 +262,6 @@ $difficulty_form->runAtServer();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php echoUOJPageFooter() ?>
|
<?php echoUOJPageFooter() ?>
|
||||||
|
@ -52,6 +52,246 @@ class UOJProblem {
|
|||||||
3500 => '#aa0000',
|
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) {
|
public static function query($id) {
|
||||||
if (!isset($id) || !validateUInt($id)) {
|
if (!isset($id) || !validateUInt($id)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1109,6 +1109,11 @@ $(document).ready(function() {
|
|||||||
[...document.querySelectorAll('[data-bs-toggle="tooltip"]')].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
|
[...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
|
// Copy button
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('.markdown-body pre, .copy-button-container pre').each(function () {
|
$('.markdown-body pre, .copy-button-container pre').each(function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user