Mail.Ru Cup 2018 Round 2 Solution

本文精选了几道算法竞赛题目并提供了详细的解题思路,包括如何通过铁轨上的站点分布判断是否能到达特定位置、如何计算头发修剪次数的变化、寻找最长连续相同幸运日等,涵盖了图论、动态规划等多种算法。

A. Metro

Solved.

题意:

有两条铁轨,都是单向的,一条是从左往右,一条是从右往左,Bob要从第一条轨道的第一个位置出发,Alice的位置处于第s个位置,有火车会行驶在铁轨上,一共有n个站点,1表示火车会在该站点停下,0表示不会,求Bob能否到达地s个位置(到达任意一边即可)

思路:

如果第一条铁轨的第一个位置为0,或者第s个位置的两条铁轨都不停,那么答案显然是$"No"$

再考虑第一条铁轨上所有为1的位置都可以到达

再考虑两条轨道是否有同一个站点都都会停下的,那么就可以到达第二条轨道,并且该站点的左边的会停下的站点都可以到达

再判断一下s站点有没有被标记即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1010
 5 int n, s, a[N], b[N];
 6 int vis[N];
 7 
 8 bool solve()
 9 {
10     if (a[1] == 0) return false;
11     if (a[s] == 0 && b[s] == 0) return false;
12     for (int i = 1; i <= n; ++i) if (a[i]) vis[i] = 1;
13     bool flag = false;
14     for (int i = n; i >= 1; --i)
15     {
16         if (a[i] && b[i]) flag = 1;
17         if (flag && b[i]) vis[i] = 1; 
18     }
19     return vis[s];
20 }
21 
22 int main()
23 {
24     while (scanf("%d%d", &n, &s) != EOF)
25     {
26         memset(vis, 0, sizeof vis);
27         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
28         for (int i = 1; i <= n; ++i) scanf("%d", b + i);
29         puts(solve() ? "YES" : "NO");    
30     }
31     return 0;
32 }
View Code

 

 

B. Alice and Hairdresser

Solved,

题意:

Alice有$n根头发,只有长度 > l 的头发才需要减,并且有相邻多根头发的长度都 > l,那么这几根可以一刀剪掉$

现在有两种操作,第一种是询问Alice如果要剪头发,最少需要减几刀,第二种是第$p$根头发增加了$d$的长度。

思路:

头发增加时,如果这根头发已经$ > l 了$ 那么不需要操作

反之,则判断一下,左右两边的头发长度

如果左右两边头发长度都$> l$ 那么下剪刀的次数 - 1  因为左右两边本来是两个连通块,现在连成一个。

如果有一边$ > l$ 有一边不是,那么下剪刀次数不变

如果两边都$ < l$ 那么下剪刀次数+1

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 int n, m, res; 
 7 ll l, a[N];
 8 
 9 int main()
10 {
11     while (scanf("%d%d%lld", &n, &m, &l) != EOF)
12     {
13         res = 0;
14         for (int i = 1; i <= n; ++i) 
15         {
16             scanf("%lld", a + i);
17             if (a[i] > l && a[i - 1] <= l) ++res; 
18         }
19         for (int i = 1, t, p, d; i <= m; ++i)
20         {
21             scanf("%d", &t);
22             if (t == 0) printf("%d\n", res);
23             else 
24             {
25                 scanf("%d%d", &p, &d);
26                 if (a[p] <= l && a[p] + d > l)  
27                 {
28                     if (a[p - 1] > l && a[p + 1] > l) --res;
29                     else if (a[p - 1] > l || a[p + 1] > l);
30                     else ++res;                    
31                 }
32                 a[p] += d;  
33             }
34         }
35     }
36     return 0;
37 }
View Code

 

 

C. Lucky Days

Upsolved.

题意:

定义一个三元组$<l, r, t>$ 表示一个周期为$t$,第$[l, r]$天里面是幸运天,现在给出$Alice 和 Bob$的两个三元组,求两人最长的连续相同的幸运天数。

 思路:

考虑两个人的起点之差是 $gcd(ta, tb)$ 用一个人的起点去逼近另一个人的起点,然后求一下答案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 ll la, lb, ra, rb, ta, tb;
 6 
 7 ll gcd(ll a, ll b)
 8 {
 9     return b ? gcd(b, a % b) : a;
10 }
11 
12 ll calc(ll la, ll ra, ll lb, ll rb)
13 {
14     return max(0ll, min(ra, rb) - max(la, lb) + 1);  
15 }
16     
17 int main()
18 {
19     while (scanf("%lld%lld%lld", &la, &ra, &ta) != EOF)
20     {
21         scanf("%lld%lld%lld", &lb, &rb, &tb);
22         if (la > lb) 
23         {
24             swap(la, lb); 
25             swap(ra, rb);
26             swap(ta, tb);
27         }
28         ll g = gcd(ta, tb);
29         ll gap = ra - la;
30         la += ((lb - la) / g) * g;
31         ra = la + gap;
32         printf("%lld\n", max(calc(la, ra, lb, rb), calc(la + g, ra + g, lb, rb)));
33     }
34     return 0;
35 }
View Code

 

 

D. Refactoring

Unsolved.

 

E. Segments on the Line

Unsolved.

 

F. Tree and XOR

Upsolved.

题意:

在一棵树种,一共有$n^2$个任意两点间的简单路径异或和,求第k大。

 思路:

显然,路上任意两点路径异或和就是两个点到根的异或和再异或

再考虑求第k大,可以二分,然后去找到有多少个比这个数小的数,如果$<= k 那么这个数就可能可以作为答案$

但这样的过程是$O(n{log^n}^2)$,显然不行

但是其实可以直接一位一位考虑,从高位到低位逐位确定,枚举当前为是否为1,如果为1,那么异或后当前为为0的都是比当前数小的数,逐步确定下去即可。

但是注意到,这个过程可以用$01Trie 完成,但是完整的01Trie空间开不下$

又考虑我们每一次确定的时候,只会用到上一层和当前层的状态,所有用滚动数组即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1000010
 6 int n, rt[N], prt[N], ch[N][2], num[N], cnt;  
 7 ll w[N], k;
 8 
 9 void init()
10 {
11     memset(num, 0, sizeof num);
12     memset(ch, 0, sizeof ch);
13 }
14 
15 int main()
16 {
17     while (scanf("%d%lld", &n, &k) != EOF)
18     {
19         init();
20         for (int i = 2, p; i <= n; ++i)
21         {
22             scanf("%d%lld", &p, w + i);
23             w[i] ^= w[p];
24         }
25         ll res = 0;
26         for (int i = 1; i <= n; ++i) rt[i] = prt[i] = 1; cnt = 1;
27         for (int s = 62; s >= 0; --s)
28         {
29             for (int i = 1; i <= cnt; ++i) ch[i][0] = ch[i][1] = num[i] = 0; cnt = 1;
30             for (int i = 1; i <= n; ++i)
31             {
32                 int id = (w[i] >> s) & 1;
33                 if (!ch[rt[i]][id]) ch[rt[i]][id] = ++cnt;
34                 rt[i] = ch[rt[i]][id];
35                 ++num[rt[i]];
36             }    
37             ll sum = 0;
38             for (int i = 1; i <= n; ++i)
39             {
40                 int id = (w[i] >> s) & 1;
41                 sum += num[ch[prt[i]][id]];
42             }
43             if (sum < k)
44             {
45                 res |= 1ll << s;
46                 k -= sum;
47                 for (int i = 1; i <= n; ++i)
48                 {
49                     int id = (w[i] >> s) & 1;
50                     prt[i] = ch[prt[i]][id ^ 1];
51                 }
52             }
53             else
54             {
55                 for (int i = 1; i <= n; ++i)
56                 {
57                     int id = (w[i] >> s) & 1;
58                     prt[i] = ch[prt[i]][id];
59                 }
60             }
61         }
62         printf("%lld\n", res);
63     }    
64     return 0;
65 }
View Code

 

G. Jellyfish Nightmare

Unsolved.

转载于:https://www.cnblogs.com/Dup4/p/9961425.html

代码下载链接: https://pan.quark.cn/s/b80bd6ed2d38 USB Type-C 协议作为USB接口的最新一代标准,致力于提供更高速的数据传输速率、更强的电源传输性能以及更灵活的连接选择。官方技术文档全面解释了该协议的各个细节,为开发者和工程师提供了系统的技术参考。以下列出该协议的一些主要技术要点: 1. **双向连接特性**:Type-C 最突出的优势在于其可逆性设计,用户可以随意正反方向插入接口,从而避免了传统USB接口常见的插接错误问题。 2. **数据传输性能**:Type-C 兼容USB 3.1规范,其最高数据传输速率可达到10 Gbps(SuperSpeed USB 10标准),同时保持对USB 3.0(5 Gbps)和USB 2.0(480 Mbps)的向下兼容性。 3. **电力供应能力**:Type-C 支持USB Power Delivery (PD) 协议,其最大供电功率可达到100W,显著超越了以往的USB接口规格,足以满足笔记本电脑等高功耗设备的使用需求。PD协议通过动态协商电源供需关系,确保设备在安全的前提下高效用电。 4. **BC1.2充电标准**:Type-C 还支持Battery Charging 1.2 (BC1.2) 标准,能够为移动设备提供快速充电服务,最大电流输出可达1.5A或3A,有效提升了充电效率。 5. **EMarker芯片功能**:在Type-C线缆中,E-Marker芯片扮演着核心角色,它负责存储并传递线缆的技术参数,如数据传输速率、最大电压等级和电流容量,从而保证设备与线缆之间的精准通信。 6. **连接器结构及引脚配置**:Type-C连接器包含24个引脚,涵盖电源线路、数据...
内容概要:本文围绕三相逆变器逆变电路的闭环控制模型展开仿真研究,重点利用Simulink平台构建完整的闭环控制系统模型,实现对输出电压与电流的高精度调控。研究内容涵盖系统建模、PI等经典控制器设计、PWM调制策略实施以及闭环反馈机制的集成与验证,深入探讨了系统在动态负载变化或外部扰动条件下的稳定性、响应速度、谐波抑制能力及动态性能表现。通过详尽的仿真分析,验证了所设计控制策略在提升电能质量和系统鲁棒性方面的有效性,为实际工程应用提供了可靠的理论依据和技术支持。; 适合人群:具备电力电子技术、自动控制理论基础,并熟悉Simulink仿真工具的研究生、科研人员及从事新能源发电、微电网、储能系统、电力系统等领域相关工作的工程技术人员。; 使用场景及目标:①用于教学与科研中深入理解三相逆变器的工作原理及其闭环控制机制;②为工业实践中逆变器控制器的设计、参数整定与优化提供高效的仿真验证平台;③支撑光伏并网、风力发电、直流微网、电动汽车充放电等应用场景下的电能质量控制与系统稳定性研究。; 阅读建议:建议读者结合电力电子与控制理论基础知识,动手搭建Simulink仿真模型,参照文档中的控制架构进行参数调试与仿真运行,重点关注控制器参数(如比例增益、积分时间)对系统动态响应和稳态精度的影响,从而深化对闭环控制原理的理解与工程应用能力。
内容概要:本文档为《【顶刊复现】配电网两阶段鲁棒故障恢复研究(Matlab代码实现)》的技术资料汇总,聚焦电力系统中配电网在故障条件下的快速恢复问题,提出一种基于两阶段鲁棒优化的故障恢复模型。该模型在第一阶段制定预恢复策略,在第二阶段根据实际不确定性(如负荷波动、分布式电源出力波动)进行动态调整,从而增强系统应对突发故障的鲁棒性与恢复能力。研究完整实现了Matlab代码仿真,并融合Benders分解、混合整数线性规划(MILP)建模及YALMIP工具包调用等关键技术,具备较强的工程复现价值。文档还附带多个前沿科研方向资源,涵盖微电网优化、储能配置、电动汽车调度、风光制氢合成氨系统、无人机路径规划及机器学习预测等领域,形成综合性科研支持体系。所有资源通过指定网盘链接与微信公众号统一提供。; 适合人群:具备电力系统、自动化、电气工程或相关专业背景,熟悉Matlab/Simulink仿真环境,有一定优化算法基础的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习并复现顶刊级别的配电网故障恢复优化模型;② 掌握两阶段鲁棒优化在电力系统不确定性建模中的应用方法;③ 深入理解Benders分解、MILP建模、YALMIP工具包调用等核心技术;④ 拓展至微电网调度、综合能源系统优化、储能配置等相关课题的研究与仿真。; 阅读建议:建议读者结合文档中提供的网盘资源与代码实例,按主题分类系统学习,优先掌握两阶段鲁棒优化的核心建模思路,并借助Matlab平台动手实践,调试代码以加深对算法流程与参数设置的理解。同时可参考文中列出的同类研究方向,拓展科研视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值