当前位置: 首页 > news >正文

Solution Set #5

qoj9237. Message(通信,adhoc,基环树)

首先这题字符串长度不固定,考虑在字符串后面加一个 \(100\ldots0\),补成一个长度为 \(1025\) 的串,把这个串传递过去后再把得到的串最后一个 \(1\) 后面的删掉即可。

设传递的信息是 \(R_1,R_2,\ldots,R_{66}\)。注意到这题只有 \(66\times 16=1056\) 个真实信息,所以第一个人必须用至多 \(31\) 次真实信息来让第二个人识别出 \(16\) 个真实位,剩余真实信息用于传递字符串。

一个很有创造性的想法是对于一个真实位 \(x\),设 \(x\) 在真实位中的后继是 \(y\)(末尾的后继就是开头),令 \(d=(y-x)\bmod 31\),让 \(R_{1,x}=R_{2,x}=\ldots=R_{d-1,x}=0,R_{d,x}=1\)\(R_{d+1,x}\sim R_{66,x}\) 传递字符串。由于 \(\sum d=31\),所以传递字符串的信息数量刚好够。

第二个人识别时,对每位 \(x\) 找到最小的 \(i\) 满足 \(R_{i,x}=1\),连一条 \(x\to (x+i)\bmod 31\) 的有向边,容易发现会连出来一个基环树。最终的真实位会在这个基环树上构成一个大小为 \(16\) 的环。注意到一个 \(31\) 个点的基环树至多只有一个大小为 \(16\) 的环,所以真实位构成的环是唯一的!求出这个环之后再依次枚举其余真实信息即可得到传递的字符串。

代码
#include "message.h"
#include <bits/stdc++.h>#ifdef ORZXKR
#include "grader.cpp"
#endifvoid send_message(std::vector<bool> M, std::vector<bool> C) {M.emplace_back(1);for (; M.size() < 1025; M.emplace_back(0)) {}std::vector<std::vector<bool>> R(66, std::vector<bool>(31));std::vector<int> pos;for (int i = 0; i < 31; ++i)if (!C[i])pos.emplace_back(i);int now = 0;for (int i = 0; i < pos.size(); ++i) {int d = (pos[(i + 1) % pos.size()] - pos[i] + 31) % 31;assert(d);R[d - 1][pos[i]] = 1;for (int j = d; j < R.size(); ++j) R[j][pos[i]] = M[now++];}for (auto &x : R) send_packet(x);
}std::vector<bool> receive_message(std::vector<std::vector<bool>> R) {static int nxt[31];for (int i = 0; i < 31; ++i) {nxt[i] = -1;for (int j = 0; j < R.size(); ++j) {if (R[j][i]) {nxt[i] = (i + j + 1) % 31;break;}}// std::cerr << i << " : " << nxt[i] << '\n';}std::vector<int> pos;for (int i = 0; i < 31; ++i) {static bool vis[31];if (nxt[i] == -1) continue;memset(vis, 0, sizeof(vis));std::vector<int> vec;for (int j = i; !vis[j]; j = nxt[j]) {vec.emplace_back(j);vis[j] = 1;}if (vec.size() == 16 && nxt[vec.back()] == vec[0]) {pos = vec;break;}}assert(pos.size() == 16);std::vector<bool> M;for (int i = 0; i < pos.size(); ++i) {int d = (pos[(i + 1) % pos.size()] - pos[i] + 31) % 31;for (int j = d; j < R.size(); ++j) M.emplace_back(R[j][pos[i]]);}for (; M.back() == 0; M.pop_back()) {}M.pop_back();return M;
}
http://www.jsqmd.com/news/740596/

相关文章:

  • 从“按部就班”到“各司其职”:重新理解面向对象与面向过程的本质区别
  • 字母ti或tu或du发音变化规则
  • 别再只调P了!用STM32的定时器编码器模式+增量式PID,让你的麦克纳姆轮小车速度控制更丝滑
  • 面向外骨骼机器人的关节力矩控制及能量回收自适应无迹卡尔曼滤波【附代码】
  • 免费开源乐谱识别工具Audiveris:5分钟将纸质乐谱变数字宝藏的完整指南
  • 用FS8A15S8 MCU搞定小风扇边充边放?实测升压到8V的完整电路与代码分享
  • 差分隐私结构化文本生成技术解析与实践
  • 完整实战指南:构建外卖订单自动化采集系统
  • 文本到音视频同步生成技术:BridgeDiT双塔架构解析
  • 3DMax 2024用户必看:Unity FBX Exporter插件安装避坑全记录(附MAXScript报错终极解法)
  • 告别wsl安装效率瓶颈,用快马ai即刻获取高效开发环境方案
  • RoboMaster 2023赛季大能量机关识别:用OpenCV findContours和膨胀操作搞定箭头合并的实战细节
  • 突破性AMD Ryzen处理器智能调优框架:SMUDebugTool革命性硬件调试方案
  • 国家自然科学基金LaTeX模板:3步极速排版指南与格式避坑手册
  • 【全栈AI开发1.0】基于 FastAPI + WebSocket + YOLOv8 的实时视频检测与统计系统
  • 告别麦克风水流声!实测Realtek R2.83驱动噪音抑制效果,附官方文件校验指南
  • 别再傻傻分不清!一张图看懂802.1、802.3、802.11到底管啥(附思维导图)
  • 【C语言物联网加密实战指南】:3种超轻量级算法(ChaCha20-Poly1305、TinyAES、XOR-PRNG)在8KB内存设备上的零依赖实现
  • 别再手动轮询了!用STM32G473的DMA+ADC实现高效数据采集(附CubeMX配置截图)
  • Claude Code 安全吗?代码隐私保护注意事项
  • 快速原型开发中如何利用 Taotoken 多模型能力进行方案选型
  • TI CC2642R1开发环境配置避坑大全:从syscfg图形化到OpenOCD调试的那些‘坑’
  • AI视频生成中的角色一致性与视觉质量优化
  • 使用 UniApp 来开发手持 PDA 的数据录入应用
  • AI抢内存致存储芯片半年涨340%,手机电脑下半年或迎普涨!
  • 3步解锁Switch控制器:JoyCon-Driver的Windows适配终极指南
  • 保姆级教程:在STM32平台上通过SPI驱动NXP TJA1145收发器(附代码片段)
  • PAJ7620手势模块避坑指南:从I2C通信失败到识别不稳定的5个常见问题
  • 文化差异如何重塑AI语言理解能力
  • STEMPHONIC框架:AI音乐生成的多轨同步技术