洛谷题单一键转 vjudge 题单
可以一键复制 vjudge 格式的题单到剪切板,注意到先点到题单的 #problems 页。
// ==UserScript==
// @name 洛谷题单转 VJudge 题单
// @namespace https://luogu-to-vjudge
// @version 0.2
// @description 将洛谷题单一键导出为 VJudge 可导入的题单格式
// @author ChatGPT & jianhe
// @match https://www.luogu.com.cn/problem/list*
// @match https://www.luogu.com.cn/training/*
// @grant GM_setClipboard
// ==/UserScript==
(function(){
'use strict';
function extractProblems(){
const res=[];
document.querySelectorAll('a[href^="/problem/"]').forEach(a=>{
const href=a.getAttribute('href');
let m;
if(m=href.match(/\/problem\/(P\d+)/))
res.push({oj:'洛谷',id:m[1]});
else if(m=href.match(/\/problem\/(CF[0-9A-Z]+)/))
res.push({oj:'CodeForces',id:m[1].slice(2)});
else if(m=href.match(/\/problem\/(AT_[\w]+)/))
res.push({oj:'AtCoder',id:m[1].slice(3)});
else if(m=href.match(/\/problem\/(UVA[0-9]+)/))
res.push({oj:'UVA',id:m[1].slice(3)});
else if(m=href.match(/\/problem\/(SP\d+)/)){
// SPOJ: 需要取题目标题的第一个词
const title = a.textContent.trim();
const firstWord = title.split(/\s+/)[0];
if(firstWord){
res.push({oj:'SPOJ',id:firstWord});
}
}
});
const mp=new Map();
res.forEach(p=>{
const k=p.oj+'-'+p.id;
if(!mp.has(k))mp.set(k,p);
});
return [...mp.values()];
}
function toVJudge(list){
return list.map(p=>`[problem:${p.oj}-${p.id}]`).join('\n');
}
function addButton(){
const btn=document.createElement('button');
btn.textContent='导出到 VJudge';
btn.style.cssText='position:fixed;right:20px;bottom:20px;z-index:9999;padding:8px 12px;border-radius:6px;background:#2d8cf0;color:#fff;border:none;cursor:pointer;';
btn.onclick=()=>{
const probs=extractProblems();
if(!probs.length){alert('未检测到题目');return;}
const txt=toVJudge(probs);
GM_setClipboard(txt);
alert('已复制到剪贴板,可直接粘贴到 VJudge 题单');
};
document.body.appendChild(btn);
}
window.addEventListener('load',addButton);
})();
以颤抖之身追赶,怀敬畏之心挑战。--《棋魂》

浙公网安备 33010602011771号