Luogu-to-Vjudge:一键跳转 VJudge 脚本
一键跳转 VJudge 脚本
新版同步于 GitHub 仓库,可以去 Star 一下。
保命声明:完全开源免费,拒绝商业化。仅供学术研究,严禁用于一切非正当行为。脚本使用了 AI 辅助制作,本文章仅作为分享,希望可以优化各位的做题体验。
2025-11-24 upt:更新了脚本源码,修复了一些跳转bug。重新提交审核,感谢管理员。
脚本简介
洛谷 和 VJudge 是两大高频使用的平台:
- 洛谷题量丰富、社区活跃;
- VJudge 支持多平台题目聚合、组队训练。
二者结合能大幅提升刷题效率。
随着洛谷 RMJ 下线,刷其他 OJ 的题目不再方便,而 VJudge 仍可提交 CF、AT、SPOJ 等题目,自由度较高。于是就有了这个脚本(网上旧脚本因洛谷新版 UI 已失效)。
方便快捷
手动在两个平台间切换、查找对应编号耗时费力。
「洛谷一键跳转 VJudge」 脚本适配洛谷新版 UI,支持 CF / SPOJ / AtCoder / UVA 四大平台题目一键跳转,自动识别题目编号并拼接 VJudge 链接,让跨平台刷题一步到位。
美观大气
视觉效果与洛谷原生按钮无缝融合:
脚本生成的按钮在背景色、字体、高度、对齐方式等方面均与原生按钮一致,不破坏页面美观;点击后于新标签页打开 VJudge 题目,不影响当前刷题进度。
使用指南
步骤 1:安装脚本管理器
在浏览器扩展商店搜索并安装 Tampermonkey 或 Violentmonkey。
相信很多人都喜欢用脚本优化做题体验。比如我:
步骤 2:添加脚本
- 打开 GitHub 仓库 下载源文件,脚本管理器会自动接管安装;
- 若未自动安装,可在脚本管理器内「新建用户脚本」,粘贴以下内容后保存:
// ==UserScript==
// @name 洛谷rmj一键跳转VJudge
// @namespace http://tampermonkey.net/
// @version 3.1
// @description 支持洛谷CF/SPOJ/AtCoder/UVA题目跳转VJudge,修复CF带数字后缀的编号匹配
// @author Justskr
// @match https://www.luogu.com.cn/problem/CF*
// @match https://www.luogu.com.cn/problem/SP*
// @match https://www.luogu.com.cn/problem/AT*
// @match https://www.luogu.com.cn/problem/UVA*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function getVjudgeUrl() {
const luoguUrl = window.location.href;
const luoguPath = window.location.pathname;
if (luoguPath.startsWith('/problem/AT_')) {
const atMatch = luoguPath.match(/AT_(\w+)/);
return atMatch ? `https://vjudge.net/problem/AtCoder-${atMatch[1]}` : null;
}
else if (luoguPath.startsWith('/problem/UVA')) {
const uvaMatch = luoguPath.match(/UVA(\d+)/);
return uvaMatch ? `https://vjudge.net/problem/UVA-${uvaMatch[1]}` : null;
}
else if (luoguPath.startsWith('/problem/CF')) {
// 修复CF编号匹配
const cfMatch = luoguPath.match(/CF(\d+[A-Za-z\d]*)/);
return cfMatch ? `https://vjudge.net/problem/CodeForces-${cfMatch[1]}` : null;
}
else if (luoguPath.startsWith('/problem/SP')) {
let spojId = null;
const originalLink = document.querySelector('a[href*="spoj.com/problems/"]');
if (originalLink) {
spojId = originalLink.href.split('/problems/')[1].replace('/', '');
}
else {
const pageText = document.body.innerText;
const spojTextMatch = pageText.match(/SPOJ\s*[-\s:]([A-Za-z0-9_-]+)/i);
spojId = spojTextMatch ? spojTextMatch[1].trim() : null;
}
return spojId ? `https://vjudge.net/problem/SPOJ-${spojId}` : null;
}
return null;
}
const copyBtn = Array.from(document.querySelectorAll('button')).find(
btn => btn.innerText.trim() === '复制题目'
);
const vjudgeUrl = getVjudgeUrl();
if (copyBtn && vjudgeUrl) {
const jumpBtn = document.createElement('button');
jumpBtn.innerText = '跳转VJudge';
const copyStyles = window.getComputedStyle(copyBtn);
[
'backgroundColor', 'color', 'border', 'borderRadius',
'padding', 'fontSize', 'fontFamily', 'cursor', 'height',
'lineHeight', 'textAlign', 'whiteSpace', 'verticalAlign',
'display', 'marginTop', 'marginBottom'
].forEach(styleProp => {
jumpBtn.style[styleProp] = copyStyles[styleProp];
});
jumpBtn.style.marginLeft = '5px';
jumpBtn.style.minWidth = copyStyles.minWidth || '80px';
jumpBtn.addEventListener('click', () => {
window.open(vjudgeUrl, '_blank');
});
copyBtn.parentNode.insertBefore(jumpBtn, copyBtn.nextSibling);
}
else if (!vjudgeUrl) {
const platform = luoguPath.match(/\/problem\/(\w+)/)[1].slice(0, 2);
console.warn(`洛谷${platform}题目跳转VJudge:未找到有效题目标识符,请检查页面格式`);
}
})();
步骤 3:一键跳转,即刻体验
打开洛谷任意支持平台的题目页,「复制题目」按钮右侧将出现「跳转 VJudge」按钮,点击即可直接跳转,无需手动输入编号!
后续可能更新「提交时重定向到 VJudge 提交界面」功能(
大概率咕咕咕)。
完结撒花!