2026第三场萌新赛

📅 2026/8/20 14:18:09
2026第三场萌新赛
2026第三场萌新赛H wnd的魔法背包用n/2算出可以让多少负数变成正数并且排序取绝对值最大的数把所有的正数和从负数变成正数的数从最大开始相加就可以了。刚开始写题提交的时候因为没有考虑负数的个数小于n/2的情况导致发生数组越界的错误。#includebits/stdc.h using namespace std; #define int long long vectorintve; signed main(){ int n; cinn; int an/2; int num; int ans0; for(int i0;in;i){ cinnum; if(num0){ ansansnum; } else{ ve.push_back(num); } } sort(ve.begin(),ve.end()); int sve.size(); if(sa){ for(int i0;ia;i){ ansans-ve[i]; } } else{ for(int i0;ive.size();i){ ansans-ve[i]; } } coutans; return 0; }J 魔法数字由于n的取值范围非常非常的大所以用字符串的方式输入n的长度为1是直接输出0和n就行了否则算出各个位数上的和让这个和一直算各个位上的和直至剩下一位数。#includebits/stdc.h using namespace std; #define int long long signed main(){ int t; cint; while(t--){ string n; cinn; int sum0; int sn.size(); if(s1){ cout0 nendl; } else{ for(int i0;is;i){ int xn[i]-0; sumsumx; } int c1; while(sum10){ int a1sum%10; int b1sum/10; int a2b1%10; int b2b1/10; int a3b2%10; int b3b2/10; sumb3a1a2a3; c; } coutc sumendl; } } }I-遗迹核心的临界容差_河南萌新联赛2026第三场郑州轻工业大学最多切K刀进行分段一段内部不能出现大于mid的差值。只要某一处差值 mid这里必须切一刀。设c 需要切割的次数初始 (c1)默认 1 整段每切一刀段数 1如果需要切割次数ck代表当前 mid 太小不满足条件。目标找到满足条件的最小mid最大值最小经典二分答案#includebits/stdc.h using namespace std; #define int long long vectorinta; int l0,r1e9; int n,k; // check猜测阈值mid判断是否可行 bool check(int mid){ int c1; // 初始整体是1段 // a内存放所有相邻元素差值 for(int i0;ia.size();i){ // 当前差值超过阈值必须切一刀段数1 if(a[i]mid){ c; } } // 需要的总段数 允许的最大段数k → 不可行 if(ck){ return false; } else{ return true; } } signed main(){ cinnk; // 只有1个核心没有相邻差值答案为0 if(n1){ cout0; return 0; } int b[n3]; // 存储原始灵压数组 for(int i0;in;i){ cinb[i]; } // 计算所有相邻两个灵压的差值绝对值存入a for(int i0;in-1;i){ int numabs(b[i1]-b[i]); a.push_back(num); } int ans0; // 二分框架求最小可行mid while(lr){ int midl(r-l)/2; // 防溢出写法 if(check(mid)){ ansmid; // mid可行记录答案 rmid-1; // 尝试寻找更小的合法阈值 } else{ lmid1; // mid不可行放大阈值 } } coutans; return 0; }G-wnd的魔法排序_河南萌新联赛2026第三场郑州轻工业大学dfs数据说明path存放当前正在构造的排列v[i] true数字i还没用false已使用isp(x)判断x是否是质数dfs流程① 终止条件path长度等于n输出一组答案② 循环i从 1 到n保证字典序③ 如果数字i未被使用若path不为空且最后一个数 i不是质数 →continue剪枝不走这条分支选中i加入path标记v [i]false递归 dfs 继续填下一个数回溯删掉path末尾元素v [i]恢复true尝试别的数字#includebits/stdc.h using namespace std; vectorboolv; //标记数组v[i]true代表数字i还没有被使用false代表已经选过 vectorintpath; //path保存当前正在构造的排列 int n; //排列长度1~n //判断x是不是质数 bool isp(int x){ if(x2){ //小于2一定不是质数 return false; } //枚举2到sqrt(x)看能否整除 for(int i2;i*ix;i){ if(x%i0){ //能整除说明有因子不是质数 return false; } } return true; //是质数 } void dfs(){ //递归出口path里面已经凑够n个数得到一组完整排列 if(path.size()n){ //输出这个排列 for(int i0;in;i){ coutpath[i] ; } coutendl; return; } //i从1到n从小到大枚举保证输出字典序 for(int i1;in;i){ if(v[i]){ //数字i还没有被选用可以尝试选它 //剪枝path不为空并且上一个数i不是质数直接跳过不递归 if(!path.empty()!isp(path.back()i)){ continue; } path.push_back(i); //把i加入当前排列末尾 v[i]false; //标记数字i已经被占用 dfs(); //递归继续填下一个位置 //回溯恢复现场 path.pop_back(); //删掉path末尾的i v[i]true; //释放数字i变回未使用状态 } } } int main(){ cinn; v.resize(n1,true); //v下标0不用1~n全部初始化为true(未使用) dfs(); //启动深度优先搜索 return 0; }A-能量任务_河南萌新联赛2026第三场郑州轻工业大学先分组把增益任务d0 全部放前面先做先攒能量消耗任务d0 全部放后面做。各组内部排序规则增益任务v1按门槛h从小到大先做门槛低的任务快速积累能量降低后续任务压力。消耗任务v2按hd从大到小排序。(hd) 任务完成后最低剩余能量。做完剩余底线越高的任务越要靠前安排避免后期能量不足。#includebits/stdc.h using namespace std; #define int long long signed main(){ int n; cinn; int h,d; // v1d0 增益任务做完能量增加 // v2d0 消耗任务做完能量减少 vectorpairint,intv1,v2; for(int i0;in;i){ cinhd; if(d0){ // 存入增益任务 pair(门槛h,能量变化d) v1.push_back(make_pair(h,d)); } else{ // 存入消耗任务 v2.push_back(make_pair(h,d)); } } // 增益任务pair默认按first(h)升序门槛低的先做 sort(v1.begin(),v1.end()); // 消耗任务按照 hd 降序排序 sort(v2.begin(),v2.end(),[](pairint,inta,pairint,intb){ return (a.firsta.second)(b.firstb.second); }); int c0; // c当前拥有的能量 int ans0; // ans总共需要额外补充的最少能量 // 先执行所有增益任务 for(auto t:v1){ int h1t.first; int d1t.second; // 当前能量达不到任务门槛需要补充能量 if(h1c){ ans ans (h1 - c); c h1; } c c d1; // 完成任务更新能量 } // 再执行所有消耗任务 for(auto t:v2){ int h2t.first; int d2t.second; if(h2c){ ans ans (h2 - c); c h2; } c c d2; } coutans; return 0; }B-三色平衡_河南萌新联赛2026第三场郑州轻工业大学用c0 c1 c2记录1 2 3出现的个数要求的子串中0 1 2的个数相等。c0[r]-c0[l]c1[r]-c1[l]c2[r]-c2[l]rl是前rl个元素0 1 2 出现的个数他们做差的值相等等价于子串中0 1 2的个数相等。对等式移项变形c0[r]-c1[r] c0[l]-c1[l] ,c0[r]-c2[r] c0[l]-c2[l]。构造 key把二元组key(c0-c1, c0-c2)作为状态。如果两个下标l、r的key完全相同则子串(l1 ~ r)合法。map 存储状态首次下标相同key只保存第一次出现的下标才能得到最长子串预先存入初始状态没有选任何字符时(c0c1c20)(key(0,0))对应下标0。遍历每一位算出当前key如果key曾经出现过计算区间长度更新答案没出现过就存入map。#includebits/stdc.h using namespace std; #define int long long signed main(){ int n; cinn; string s; cins; // mpkey(c0‑c1, c0‑c2) value第一次出现该状态的下标 mappairint,int,intmp; mp[{0,0}]0; //初始前缀状态下标0 int ans0; int c00,c10,c20; //前缀计数0、1、2的总数量 // i是前缀下标必须跑满 1~n for(int i1;is.size();i){ char cs[i-1]; //s字符串下标从0开始 if(c0) c0; if(c1) c1; if(c2) c2; // 计算当前位置的状态key int xc0-c1; int yc0-c2; pairint,intc_key{x,y}; if(mp.count(c_key)){ //之前出现过该状态更新最长长度 ansmax(ans,i-mp[c_key]); } else{ //第一次出现记录当前前缀下标 mp[c_key]i; } } coutans; return 0; }