1 条题解

  • 0
    @ 2025-11-18 8:52:26

    题解:How to Avoid Disqualification in 75 Easy Steps

    题目分析

    本题是一道交互题,核心目标是通过最多 RR 个扫地机器人和 HH 小时,确定两位主席在 110001 \sim 1000 中的位置(允许位置相同)。机器人的核心功能是探测一组位置中是否存在至少一位主席,返回结果为 11(存在)或 00(不存在)。

    关键约束

    • 机器人总数限制:最多调用 sendsend 函数 RR 次,每次发送的位置需两两不同。
    • 时间限制:最多调用 waitwait 函数 HH 次,每次 waitwait 对应 1 小时。
    • 交互独立性:机器人探测与结果返回异步,waitwait 会返回上一次 waitwait 后所有 sendsend 的结果。

    核心挑战

    需根据不同的 RRHH 组合设计策略,在资源限制内高效缩小可能的位置对 (a,b)(a,b),最终唯一确定答案。

    算法设计

    代码针对不同的 RRHH 组合设计了 4 种策略,分别对应不同子任务,核心思路均为“分治+编码压缩”,利用二进制或自定义编码降低探测维度。

    策略 1:Work0(R=10,H=1R=10, H=1,主席同位置)

    适用场景

    子任务 1:R=10R=10H=1H=1 且两位主席位置相同(即只需确定单个位置)。

    核心思路:二进制编码探测

    • 110001 \sim 1000 的每个位置映射到 10 位二进制数(210=102410002^{10}=1024 \geq 1000)。
    • 构造 10 个探测集合:第 jj 个集合包含所有二进制第 jj 位为 11 的位置。
    • 一次性发送 10 个机器人(H=1H=1 支持批量发送后统一等待),根据返回结果的二进制组合确定目标位置。

    示例

    若返回结果为 {1,0,1,0,}\{1,0,1,0,\dots\},则目标位置的二进制第 00 位、第 22 位为 11,其余为 00,转换为十进制即为答案。

    策略 2:Work1(H=20H=20R=H=20R=H=20

    适用场景

    子任务 2:R=H=20R=H=20,时间充足但机器人数量有限。

    核心思路:二分查找单位置

    由于 HH 充足(20 小时),可分两次二分查找分别确定两个主席的位置:

    1. 第一次二分:每次发送机器人探测当前区间的左半部分,根据返回结果 11(目标在左半)或 00(目标在右半)缩小范围,直至找到第一个位置 ans0ans0
    2. 第二次二分:同理找到第二个位置 ans1ans1(允许与 ans0ans0 相同)。

    复杂度分析

    • 二分查找单次复杂度:log2100010\log_2 1000 \approx 10sendsendwaitwait,两次共需约 20 次,刚好匹配 R=H=20R=H=20 的限制。

    策略 3:Work2(H=2H=2

    适用场景

    子任务 3:R=30R=30H=2H=2,时间有限但机器人数量充足。

    核心思路:双编码分层探测

    • 第一层编码(20 个机器人,H=1H=1):为每个位置分配 10 位二进制,构造 2×102 \times 10 个集合(第 2j2j 位为原第 jj 位,第 2j+12j+1 位为原第 jj 位的反)。通过返回结果初步筛选可能的位置,确定二进制中“确定位”和“不确定位”。
    • 第二层编码(最多 10 个机器人,H=2H=2):针对不确定位,构造补充探测集合,进一步缩小范围,最终确定两个位置。

    关键优化

    通过双编码压缩探测维度,将原本需要 O(10002)O(1000^2) 的位置对探测,压缩到 O(20+10)O(20 + 10) 个机器人,适配 H=2H=2 的时间限制。

    策略 4:Work3(H=1H=1R75R \leq 75

    适用场景

    子任务 4:H=1H=1R75R \leq 75(重点优化 R26R \leq 26 以拿满分),需一次性发送所有机器人并等待结果。

    核心思路:自定义编码去重+集合筛选

    • 自定义编码数组 DD:包含 1000 个互不相同的整数,每个整数对应一个位置的“特征编码”。
    • 位置对编码:对于位置对 (i,j)(i,j)iji \leq j),其编码为 D[i]D[j]D[i] | D[j](按位或),且保证所有位置对的编码互不重复(通过预排序验证去重)。
    • 构造 26 个探测集合:第 jj 个集合包含所有 D[i]D[i]jj 位为 11 的位置。
    • 筛选逻辑:根据返回结果,筛选出编码特征与结果完全匹配的位置对,即为答案。

    核心优势

    • 编码去重:通过自定义 DD 数组确保位置对与编码一一对应,避免歧义。
    • 高效压缩:26 个探测集合即可覆盖所有位置对特征(2262^{26} 足够区分 1000×10001000 \times 1000 个位置对),适配 H=1H=1R26R \leq 26 的严格限制。

    代码关键模块解析

    1. 编码与探测集合构造

    • 二进制编码(Work0/Work2):将位置映射到二进制位,通过位运算构造探测集合。
    • 自定义编码(Work3):DD 数组提供独特特征编码,通过按位或合并位置对信息,确保编码唯一性。

    2. 结果解析逻辑

    • 二进制结果转位置:将 waitwait 返回的 0/10/1 序列视为二进制数,转换为十进制位置(Work0)。
    • 集合筛选:通过位运算筛选出编码特征与探测结果匹配的位置/位置对(Work2/Work3)。

    3. 资源适配

    代码在 scout 函数中根据 RRHH 的值自动选择策略,适配不同子任务的资源限制。

    复杂度分析

    策略 时间复杂度(HH 空间复杂度(RR 适用场景
    Work0 O(1)O(1) O(logN)O(\log N) R=10,H=1R=10, H=1,同位置
    Work1 O(logN)O(\log N) R=H=20R=H=20,充足时间
    Work2 O(2)O(2) R=30,H=2R=30, H=2,中等资源
    Work3 O(1)O(1) O(log(N2))O(\log(N^2)) R75,H=1R \leq 75, H=1,严格时间

    注:N=1000N=1000 为位置总数,logN10\log N \approx 10log(N2)20\log(N^2) \approx 20,策略 3 实际使用 26 个机器人,满足满分要求。

    关键优化点

    1. 编码去重:Work3 中 DD 数组的设计确保位置对编码唯一,避免多解歧义。
    2. 批量探测:适配 H=1H=1 的场景,一次性发送所有机器人,减少时间消耗。
    3. 分治压缩:通过二进制或自定义编码,将二维位置对问题转化为一维探测问题,降低资源消耗。

    注意事项

    1. 位置合法性:每次 sendsend 的位置必须在 110001 \sim 1000 且两两不同,否则会被判为非法。
    2. 资源控制:严格遵守 sendsendwaitwait 的调用次数限制,超限制会直接终止程序。
    3. 交互逻辑waitwait 的返回结果与 sendsend 顺序一致,需妥善记录发送顺序以匹配结果。

    完整代码

    #include "avoid.h"
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef pair<int, int> PII;
    
    const int M = 70;
    
    int n = 1000;
    
    inline PII Work0() {
        vector<int> p[M];
    
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < 10; j ++)
                if (i >> j & 1)
                    p[j].push_back(i + 1);
    
        for (int i = 0; i < 10; i ++)
            send(p[i]);
    
        vector<int> r = wait();
        int ans = 0;
    
        for (int i = 0; i < 10; i ++)
            ans |= r[i] << i;
    
        return make_pair(ans + 1, ans + 1);
    }
    
    int ans0, ans1;
    inline void Solve11(int l, int r) {
        if (l == r) {
            if (ans0)
                ans1 = l;
            else
                ans0 = l;
    
            return ;
        }
    
        vector<int> pl;
        int mid = (l + r) >> 1;
    
        for (int i = l; i <= mid; i ++)
            pl.push_back(i);
    
        send(pl);
        vector<int> R = wait();
    
        if (R[0])
            Solve11(l, mid);
        else
            Solve11(mid + 1, r);
    }
    inline void Solve12(int l, int r) {
        if (l == r) {
            if (ans0)
                ans1 = l;
            else
                ans0 = l;
    
            return ;
        }
    
        vector<int> pr;
        int mid = (l + r) >> 1;
    
        for (int i = mid + 1; i <= r; i ++)
            pr.push_back(i);
    
        send(pr);
        vector<int> R = wait();
    
        if (R[0])
            Solve12(mid + 1, r);
        else
            Solve12(l, mid);
    }
    inline PII Work1() {
        Solve11(1, n), Solve12(1, n);
        return make_pair(ans0, ans1);
    }
    
    inline PII Work2() {
        vector<int> p[M];
    
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < 10; j ++)
                p[j << 1 | (i >> j & 1)].push_back(i + 1);
    
        for (int i = 0; i < 20; i ++)
            send(p[i]);
    
        vector<int> r = wait();
        vector<int> p1;
    
        for (int i = 0; i < 10; i ++) {
            if (r[i << 1] && r[i << 1 | 1])
                p1.push_back(i);
            else
                ans0 |= r[i << 1 | 1] << i;
        }
    
        ans1 = ans0;
        int m = p1.size();
    
        if (!m)
            return make_pair(ans0 + 1, ans1 + 1);
    
        ans1 |= 1 << p1[0];
        cerr << p1[0] << endl;
    
        if (m == 1)
            return make_pair(ans0 + 1, ans1 + 1);
    
        for (int i = 0; i < m - 1; i ++) {
            p[i].clear();
    
            for (int j = 0; j < 1 << (m - 1); j ++) {
                if (!(j >> i & 1))
                    continue;
    
                int t = ans1;
    
                for (int k = 0; k < m - 1; k ++)
                    if (j >> k & 1)
                        t |= 1 << p1[k + 1];
    
                if (t < n)
                    p[i].push_back(t + 1);
            }
        }
    
        for (int i = 0; i < m - 1; i ++)
            send(p[i]);
    
        r = wait();
    
        for (int i = 0; i < m - 1; i ++) {
            if (r[i])
                ans1 |= 1 << p1[i + 1];
            else
                ans0 |= 1 << p1[i + 1];
        }
    
        return make_pair(ans0 + 1, ans1 + 1);
    }
    
    const long long D[] = {
        255, 1823, 2919, 3499, 3795, 5037, 5491, 6493, 7062, 9139, 9581, 10813, 11209, 11669, 13455, 16033, 17358, 17912, 19130, 21110, 22059, 22727, 26309, 27762, 28955, 31116, 33749, 34278, 35290, 36457, 37467, 38967, 42819, 45285, 45358, 48153, 50579, 52302, 53705, 54332, 61064, 67182, 67902, 70364, 72870, 75444, 77945, 79298, 79621, 82263, 83102, 84629, 88673, 89416, 92323, 99501, 102154, 104554, 107364, 111250, 121604, 122895, 132725, 134797, 135907, 137848, 138315, 139708, 140890, 148329, 148901, 149972, 153898, 155703, 159520, 161873, 166706, 169304, 174250, 179072, 185105, 187584, 193542, 197616, 202921, 205191, 209939, 210958, 221740, 229582, 232005, 241985, 246360, 263847, 264689, 267853, 268088, 270935, 276523, 278845, 281894, 282842, 291985, 295658, 297628, 302402, 304329, 311651, 312916, 321810, 324099, 330515, 332642, 339014, 346189, 349828, 360603, 369713, 376320, 379296, 386368, 394700, 396311, 406154, 406817, 418020, 430916, 445488, 450712, 475909, 479282, 509057, 526009, 529644, 531274, 531905, 532854, 536071, 537297, 541620, 543027, 547866, 550786, 551500, 561310, 563568, 569954, 574023, 581721, 582820, 590237, 592981, 599457, 610350, 621600, 625187, 627723, 641728, 656626, 669890, 674017, 688461, 689926, 694531, 723602, 724552, 729866, 757936, 788694, 793125, 795480, 797752, 806657, 820561, 860302, 866576, 923520, 926731, 934426, 938068, 944448, 960524, 1036800, 999880, 1017989, 1051230, 1053877, 1054534, 1056044, 1057642, 1061560, 1067339, 1068593, 1070800, 1073933, 1082780, 1084070, 1091937, 1098922, 1115335, 1118503, 1121928, 1124784, 1134824, 1139786, 1148466, 1153553, 1159252, 1163564, 1180315, 1190662, 1200206, 1206298, 1215570, 1218712, 1222149, 1246028, 1247345, 1270656, 1294355, 1311698, 1316227, 1320588, 1321186, 1323337, 1333385, 1340512, 1360688, 1379369, 1403920, 1441965, 1444641, 1475876, 1542336, 1573857, 1583320, 1590317, 1601826, 1614276, 1615384, 1623362, 1640324, 1663252, 1677318, 1716756, 1722128, 1835434, 1869835, 1872424, 1905232, 1974913, 2007088, 2032664, 2100444, 2102938, 2106595, 2107471, 2110292, 2112290, 2115378, 2120112, 2122194, 2130235, 2133780, 2142761, 2146845, 2151506, 2163433, 2166113, 2166935, 2188049, 2192396, 2196812, 2206018, 2226177, 2228798, 2247299, 2249356, 2263249, 2285642, 2295331, 2298274, 2303252, 2315360, 2328256, 2360172, 2362649, 2369590, 2382408, 2394277, 2412932, 2425286, 2474040, 2491057, 2497696, 2502789, 2564688, 2628870, 2638029, 2646186, 2650629, 2655656, 2657154, 2689648, 2697380, 2706562, 2752867, 2755684, 2765896, 2801812, 2887793, 2892323, 2901344, 2950676, 2953481, 2990720, 3016778, 3051650, 3148906, 3165508, 3171846, 3182607, 3183072, 3189266, 3213701, 3252362, 3277913, 3287077, 3330082, 3353096, 3421952, 3441348, 3477556, 3506249, 3556482, 3606531, 3670840, 3679505, 3681920, 3723393, 3805706, 3885072, 4014113, 4197605, 4199641, 4203244, 4203579, 4204883, 4208952, 4214672, 4215683, 4219505, 4227900, 4229263, 4232994, 4238664, 4248645, 4251798, 4260698, 4266690, 4276454, 4282520, 4297253, 4305312, 4310120, 4331022, 4336212, 4336678, 4342046, 4346544, 4383753, 4391091, 4419652, 4426755, 4460956, 4467586, 4475000, 4479508, 4491013, 4503620, 4530469, 4548098, 4563720, 4590248, 4592065, 4605002, 4620934, 4662312, 4720488, 4744724, 4751475, 4755076, 4758081, 4761761, 4794393, 4801289, 4851089, 4853831, 4885792, 4931724, 4998305, 5003522, 5013801, 5051410, 5056704, 5258245, 5288130, 5296177, 5326210, 5374324, 5383376, 5390915, 5441928, 5472404, 5472777, 5521828, 5578828, 5640290, 5768215, 5779848, 5808676, 5898840, 5966340, 6097184, 6301066, 6311975, 6321728, 6330456, 6359594, 6367809, 6375446, 6424993, 6456370, 6460800, 6488184, 6555234, 6558345, 6578217, 6619537, 6725952, 6799364, 6828384, 6837505, 6850058, 6916108, 6931472, 7106688, 7344788, 7357720, 7362625, 7442450, 7602262, 7651338, 8069121, 8130584, 8392524, 8395417, 8395862, 8399006, 8401384, 8406754, 8409445, 8415000, 8423344, 8431146, 8436296, 8440105, 8446997, 8455481, 8462923, 8473796, 8476208, 8480006, 8489076, 8492550, 8497537, 8507540, 8523823, 8544913, 8564873, 8572418, 8581408, 8585626, 8585893, 8596288, 8615040, 8655270, 8660306, 8665200, 8668268, 8671758, 8676228, 8717249, 8717327, 8751682, 8784322, 8804896, 8827920, 8847668, 8917767, 8925722, 8931467, 8947077, 8956994, 8958225, 8982288, 9035810, 9046105, 9077788, 9118816, 9177357, 9183401, 9195587, 9229344, 9338980, 9375784, 9437591, 9474595, 9520163, 9571601, 9576525, 9590789, 9602209, 9699443, 9733762, 9736220, 9756681, 9766304, 9806096, 9847828, 9932802, 9973860, 9978200, 9996680, 10027714, 10207240, 10365952, 10490697, 10494373, 10513448, 10537296, 10563666, 10619164, 10649987, 10689152, 10760268, 10785801, 10863360, 10944736, 11011155, 11015716, 11100304, 11113024, 11150850, 11534542, 11541633, 11576368, 11622432, 11800784, 11846720, 12093445, 12190468, 12321376, 12596612, 12599375, 12620114, 12632968, 12715331, 12722738, 12749000, 12785924, 12846617, 12852234, 12871840, 12916032, 13107758, 13127984, 13177985, 13256256, 13287441, 13371922, 13635330, 13666864, 13676584, 13699217, 13776384, 13779233, 14237764, 14290962, 14418689, 14717104, 14731777, 14745772, 14822528, 14844200, 15468609, 15729600, 15786240, 16130052, 16320000, 16783304, 16789092, 16789813, 16791642, 16791939, 16797318, 16803153, 16813361, 16814265, 16816653, 16821270, 16827298, 16834920, 16843319, 16845288, 16860697, 16876361, 16879248, 16893989, 16896138, 16908635, 16914068, 16917984, 16935173, 16950028, 16978246, 16984162, 16998674, 17011240, 17040171, 17062224, 17072470, 17076833, 17096837, 17106514, 17118472, 17180848, 17188008, 17190985, 17242129, 17302862, 17306393, 17309895, 17324073, 17367691, 17425416, 17438304, 17451036, 17461384, 17487104, 17515056, 17539089, 17569954, 17575296, 17581330, 17629860, 17728066, 17828689, 17839171, 17857056, 17865800, 17875156, 17913092, 17948832, 17965762, 17973414, 18023569, 18058244, 18091146, 18104853, 18123137, 18129666, 18221156, 18367176, 18401297, 18415674, 18487680, 18490632, 18685957, 18885260, 18886896, 18926176, 18941979, 18944312, 18964547, 19039753, 19121154, 19137621, 19192832, 19268482, 19343364, 19401238, 19425360, 19476994, 19480968, 19943449, 19989092, 20022312, 20186500, 20219910, 20328464, 20448464, 20461569, 20465184, 20973226, 20996280, 21016587, 21042288, 21053793, 21121545, 21140516, 21171968, 21235758, 21246530, 21512532, 21528966, 21660289, 21860416, 21901316, 22026416, 22044686, 22086560, 22155525, 22283352, 22446097, 22544549, 22761472, 22815776, 23077013, 23102785, 23205956, 23225600, 23300224, 23335684, 23600136, 23658570, 23889024, 24117347, 24265220, 25034754, 25185456, 25186362, 25192970, 25206988, 25236037, 25330260, 25437348, 25464906, 25496076, 25694610, 25701152, 25762112, 25853987, 26217824, 26222652, 26329153, 26423297, 26494994, 26772993, 26814480, 27001924, 27267363, 27284548, 27330336, 27397648, 27476001, 27525688, 27820808, 27934726, 29360820, 29361545, 29442256, 29634577, 29754560, 30418947, 30447620, 31522823, 31592584, 32514128, 33030184, 31825952, 33561060, 33564624, 33568022, 33571545, 33572911, 33576716, 33583472, 33590041, 33594501, 33596046, 33613089, 33623280, 33624267, 33630746, 33639970, 33677712, 33687394, 33695891, 33709076, 33710172, 33718505, 33728564, 33734982, 33756040, 33757520, 33777153, 33821723, 33822983, 33824336, 33826216, 33861794, 33876033, 33884809, 33899587, 33919424, 33956456, 34082442, 34091037, 34112566, 34120488, 34141696, 34146633, 34161058, 34161944, 34188416, 34212548, 34230820, 34276644, 34343840, 34418784, 34473009, 34496642, 34606362, 34632321, 34640081, 34644043, 34669116, 34673473, 34695300, 34735288, 34739715, 34841616, 34867604, 34876452, 34882118, 34996568, 35046408, 35137571, 35217473, 35280000, 35303425, 35394566, 35422560, 35457538, 35656805, 35666072, 35692721, 35719948, 35735120, 35783239, 35787034, 35864728, 35934880, 35948872, 36061569, 36078660, 36200518, 36214080, 36225297, 36290596, 36464648, 36706325, 36708745, 36767490, 36834176, 36856352, 36966540, 37224626, 37617729, 37749234, 37804041, 37819468, 37849378, 37880971, 37888900, 37925392, 38011670, 38014273, 38043725, 38110736, 38291602, 38306200, 38342705, 38379526, 38818068, 38855232, 38872328, 38879393, 39012354, 39098624, 39129218, 39323692, 39324752, 39856800, 40009765, 40370821, 40517672, 40567104, 40972800, 41176064, 41949738, 41964930, 42033201, 42043411, 42074901, 42087688, 42107466, 42221874, 42238101, 42299400, 42337924, 42471664, 42492736, 42549765, 42762506, 42958849, 43008396, 43061274, 43393058, 43827712, 44048500, 44077123, 44117008, 44353568, 44443649, 44701698, 45090084, 45621776, 46203942, 46252056, 46336513, 46408384, 46441473, 46475268, 46661925, 47192130, 47321220, 47382568, 48251074, 49545225, 50349258, 50373155, 50430260, 50474024, 50486016, 50667713, 50675846, 50728988, 50759683, 50858098, 50868612, 50889664, 51127810, 51139073, 51415068, 51445976, 51490818, 51775008, 51953924, 52445454, 52572226, 52626592, 52709393, 52985987, 52986904, 53813256, 54002185, 54531218, 54535685, 54624900, 54690128, 54812936, 55060752, 56623920, 56692772, 56899584, 58754272, 58756864, 58853413, 59250700, 59310339, 59785858, 59901008, 60097280, 60823936, 61411344, 62935105, 63594496, 25232514
    };
    bitset<1005> st[M], f;
    long long s[1000005];
    inline PII Work3() {
        int tot = 0;
    
        for (int i = 0; i < n; i ++)
            for (int j = i; j < n; j ++)
                s[ ++ tot] = D[i] | D[j];
    
        sort(s + 1, s + tot + 1);
    
        for (int i = 2; i <= tot; i ++) {
            if (s[i] == s[i - 1])
                printf("!%lld %lld\n", s[i], s[i - 1]);
    
            assert(s[i] != s[i - 1]);
        }
    
        int m = 26;
        vector<int> p[M];
    
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < m; j ++)
                if (D[i] >> j & 1)
                    st[j].set(i), p[j].push_back(i + 1);
    
        for (int i = 0; i < m; i ++)
            send(p[i]);
    
        vector<int> r = wait();
    
        for (int i = 0; i < n; i ++)
            f.set(i);
    
        for (int i = 0; i < m; i ++)
            if (!r[i])
                f &= ~st[i];
    
        for (int i = 0; i < n; i ++)
            for (int j = i; j < n; j ++)
                if (f[i] && f[j]) {
                    int flag = 1;
    
                    for (int k = 0; k < m; k ++)
                        if (r[k] && !st[k][i] && !st[k][j]) {
                            flag = 0;
                            break;
                        }
    
                    if (flag)
                        return make_pair(i + 1, j + 1);
                }
    
        return make_pair(-1, -1);
    }
    
    PII scout(int R, int H) {
        if (R == 10)
            return Work0();
        else if (H == 20)
            return Work1();
        else if (H == 2)
            return Work2();
        else
            return Work3();
    }
    

    该代码通过针对性策略适配不同子任务,在资源限制内高效完成位置探测,尤其 Work3 策略仅需 26 个机器人即可满足子任务 4 的满分要求,是编码压缩与交互逻辑的典型应用。

    • 1

    #4022. 「CEOI2023」How to Avoid Disqualification in 75 Easy Steps

    信息

    ID
    5346
    时间
    250ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者