传送门: 洛谷 P1647锁


题目描述

给出N和K,要求生成从000到2N−12^{N-1}2N−1的一个序列,序列的第一项为000,并且该序列满足以下三个条件:

(1) 序列长度为2N2^N2N,保证000到2N−12^{N-1}2N−1的每个数都用了且只用了一次。

(2) 序列中任意两相邻的数都是由前一个数在其二进制下,改变了具有相同值的若干个位而形成的,即把其中若干个000变为111,或把其中若干个111变为000,并且只能二选一。

(3) 当存在多个序列满足前两个条件的时候,要保证字典序最小,即由前一个数生成后一个数的时候,要挑值最小的数(当然是满足前两个条件的情况下)。

现问你这个序列前KKK项中的最大值是多少,输出其二进制形式,注意一定要输出NNN位,包括前导零。


分析

头痛的题,看起来毫无头绪,打个表找找规律吧(暴力有606060分,可惜当时暴力都没有打)

1 : 0 1
2 : 00 01 11 10
3 : 000 001 011 010 110 100 101 111
4 : 0000 0001 0011 0010 0110 0100 0101 0111 1111 1000 1001 1011 1010 1110 1100 1101
5 : 00000 00001 00011 00010 00110 00100 00101 00111 01111 01000 01001 01011 01010 01110 01100 01101 11101 10000 10001 10011 10010 10110 10100 10101 10111 11111 11000 11001 11011 11010 11110 11100

1 : 0 1
2 : 0 1 3 2
3 : 0 1 3 2 6 4 5 7
4 : 0 1 3 2 6 4 5 7 15 8 9 11 10 14 12 13
5 : 0 1 3 2 6 4 5 7 15 8 9 11 10 14 12 13 29 16 17 19 18 22 20 21 23 31 24 25 27 26 30 28
6 : 0 1 3 2 6 4 5 7 15 8 9 11 10 14 12 13 29 16 17 19 18 22 20 21 23 31 24 25 27 26 30 28 60 32 33 35 34 38 36 37 39 47 40 41 43 42 46 44 45 61 48 49 51 50 54 52 53 55 63 56 57 59 58 62

无论是十进制还是二进制,相信规律还是能找出来的吧。对此,本人先抛砖引玉,仅列出所用到几点(参考的二进制):

  1. 数的位置是确定的
  2. 对于一个nnn位的二进制,最高位出现111的位置是2n−1+12^{n - 1} + 12n−1+1
  3. 忽略掉nnn位二进制的最高位,发现位于[1,2n−1][1,2^{n - 1}][1,2n−1]的数与位于[2n−1+1,2n][2^{n - 1} + 1, 2^n][2n−1+1,2n]的数仅仅是由前者整体右移一位(最后一位补至第一位) 得来
    Eg.Eg.Eg.
    000001011010110100101111000 \quad 001 \quad 011 \quad 010 \quad 110 \quad 100 \quad 101 \quad 111000001011010110100101111
    忽略掉最高位后明显分为两个相似的部分(没对齐就将就一下吧)
    (0)00(0)01(0)11(0)10\quad \quad \quad(0)00 \quad (0)01 \quad (0)11 \quad (0)10(0)00(0)01(0)11(0)10
    (1)10(1)00(1)01(1)11(1)10 \quad (1)00 \quad (1)01 \quad (1)11(1)10(1)00(1)01(1)11

对此,可以考虑利用上述性质来解题了(找到规律的你们应该可以忽略掉下面的一大段废话了吧):

  1. 利用 规律222 找到前kkk位数中,二进制下第一个111的位置xxx(找最高的),然后去掉那些对应位置为000的(缩小查找的区间)。
  2. 利用 规律333 递归处理后x−1x - 1x−1位

代码

#include <cstdio>
#include <cstdlib>#define IL inline
#define open(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout);
#define close fclose(stdin); fclose(stdout);using namespace std;typedef long long ll;IL ll read()
{ll sum = 0;int k = 1;char c = getchar();for(;'0' > c || c > '9'; c = getchar())if(c == '-') k = 0;for(;'0' <= c && c <= '9'; c = getchar())sum = sum * 10 + c - '0';return k ? sum : -sum;
}int n;
ll m;
IL ll max_(ll x, ll y) { return x > y ? x : y; }IL void wri(ll x, int t)
{if(t - 1) wri(x >> 1, t - 1);putchar(x & 1 ? '1' : '0');
}IL ll power(int t)
{ll sum = 1;for(; t; --t) sum <<= 1;return sum;
}//查找的区间[l, r],由于long long范围,位运算算不出来,所以直接处理成2^x
IL ll get(ll l, ll r, ll k)
{k >>= 1;//边界if(r == 1) return 0;if(r == 2) return 1;ll sum = 0;for(;k >= r; k >>= 1);//找最高位的1l = max_(l, k | 1);l -= k + 1;r -= k + 1;//特殊处理一下左移if(!l){if(l == r) sum = get(k, k, k); else sum = max_(get(1, r, k), get(k, k, k));}else{sum = get(l, r, k);}return sum + k;//加上当前这一位的1
}int main()
{open("lock")n = read();  m = read();//转化为二进制输出wri(get(1, m, power(n)), n);closereturn 0;
}

[洛谷 P1647]锁 --- 规律 + 二进制相关推荐

  1. 洛谷-P1010-幂次方-普及(摁写+递归/二进制+递归)

    一 题目描述 二 示例及提示 输入格式 一行一个正整数 n. 输出格式 符合约定的 n的 0,2 表示(在表示中不能有空格). 输入输出样例 输入 #1 1315 输出 #1 2(2(2+2(0))+ ...

  2. 麦森数(洛谷P1045题题解,Java语言描述)

    题目要求 题目链接 分析 这题挺经典的,快速幂取模算法,如果求出大数再取模就可能T掉. 之前有篇文章写了这个算法:<快速幂算法详解&&快速幂取模算法详解> 既然是Java, ...

  3. 树状数组入门——以洛谷3374为例

    树状数组入门 含义:顾名思义,用树状表示的数组 功能:是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log( ...

  4. [洛谷]CON1466 洛谷2017春节联欢赛 Hello Dingyou题解 Bzoj4763雪辉

    题目来源:https://www.luogu.org/contest/show?tid=1466 创建时间:2017/3/13 18:33 镇楼图:       猜猜她是谁~ 解题思路: 春节居然也有 ...

  5. 洛谷 P3216 [HNOI2011]数学作业

    PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P3216 [HNOI2011]数学作业 题目 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正 ...

  6. 洛谷 - 试炼场(全部题目备份)

    整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...

  7. 洛谷P4301 [CQOI2013]新Nim游戏

    洛谷P4301 [CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火 ...

  8. 【洛谷4005】小Y和地铁(搜索)

    [洛谷4005]小Y和地铁(搜索) 题面 洛谷 有点长. 题解 首先对于需要被链接的两个点,样例中间基本上把所有的情况都给出来了. 但是还缺了一种从下面绕道左边在从整个上面跨过去在从右边绕到下面来的情 ...

  9. 洛谷——P1328 生活大爆炸版石头剪刀布

    题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第8集中出现了一种石头剪刀布的升级版游戏. 升级版游戏在传统的 ...

最新文章

  1. java字符串去掉空格
  2. python线程退出_python子线程退出及线程退出控制的代码
  3. VIPKID:笔试题(数组中和为0的一对数的数量,十进制转二进制中1的个数)
  4. VC-SDK路报(预备知识与概念介绍)
  5. 算法学习笔记(八) 动态规划的一般求解方法
  6. JAVA数组元素的遍历_Java数组元素的遍历
  7. cesium导入kml文件
  8. 蓝牙音乐SRC侧的安卓实现
  9. 目录遍历(Directory traversal)
  10. 自然摄影指南——第一章:曝光:使用相机的测光表
  11. 国内最优质的10个小众网站,你知道几个?
  12. TikTok涨粉?参考抖音?账号增粉解析!
  13. JustOj 2040: 王胖子买零食 (贪心)
  14. 公有继承,私有继承,保护继承的区别
  15. 大话设计模式之爱你一万年:系列文章 - 导读
  16. MongoDB——基本命令
  17. 文学鼻祖网站关闭服务器,华语网络文学鼻祖网站正式关闭服务器,有你的青春回忆吗?...
  18. 美国证监会因可疑交易和社交媒体活动 暂停15家公司股票交易
  19. 基于MT7621A 的无线串口服务器调试
  20. iTunes还原或升级iphone出现未知错误14?教你轻松解决这个错误问题!

热门文章

  1. HTML5终极备忘大全(图片版+文字版)
  2. 900句--熟背后交流无障碍
  3. Linux网络编程之获取网络天气信息
  4. winform datagridview控件设置列标题字体大小无效问题
  5. String.Empty和的区别
  6. latex 精准调整控制表格每一行之间的行距
  7. php 给视频添加水印,记php调用ffmpeg给视频加文字水印
  8. matlab仿真限幅发散,simulink仿真收敛,但用m文件实现却是发散的,是怎么回事?...
  9. 高级查询组件dynamicCondition升级为v2.0.0版本(一)——使用步骤
  10. Python sum()函数