进入2012年的题 codility上的题目开始变难,变得有意思起来。给定两个长度在[1..300000]的只包含0和1的串S和T,它们是2进制表示的,S表示的数A不大于T表示的数B,即A<=B,且A > 0。还有一个参数是K, 1<=K<=30,问[A..B]之间有多少个数满足它们的2进制表示任意两个1之间至少有个0。(如果一个数2进制表示只有1个1,认为它是满足条件的)。

结果 对  1000000007取模。

要求复杂度:时间空间都是O(log(A +B))

分析: 我们求[0..B]之间有多少个数满足要求…… 一个显然的dp。不过我写了好久,因为式子没写对……设dp[n]表示n位满足要求的2进制数(允许首位是0)的个数。

规定dp[0] = 1, dp[1] = 2。dp[1] = 2是只有1位时,它为0或者为1都可以。 那么我们考虑dp[n] (n > 1),如果它首位为0,则它的后面(n - 1)位一定满足条件。如果它首位为1,则它后必须有K个0,再接一个有效的数即dp[n] = dp[n - 1] + dp[n - k - 1]。 这里要注意当n - k - 1 < 0时,我们要加1,也就是初始条件对于dp[x] = 1 if x <= 0。这里的原因是这样的,当首位为1时,后面位数不足K位时,全为0式满足条件的。 于是统一一下,方程为dp[n] = dp[n - 1] + dp[n - k - 1] 初始条件是 dp[x] = 1 if x <= 0。

后面的问题就简单了,我们沿着B的高位走,每次遇到1,试图把它变成0,注意上一次1的位置,再后面一个位置接一个合法的数(利用dp)的结果。实际上我们对于B的每个1bit,都尝试一下变成0,这样每次产生的数必然和B不同。就是枚举了第一个和B不相同的位。还有一点要注意,如果不改变B的1bit,已经非法的话,就要退出。这里还是有一些细节要处理的。 最后求的是num [0..B] - num [0..A - 1]。

代码:

// you can also use includes, for example:
// #include <algorithm>
#include <vector> const int M = 1000000007; vector<int> dp; int add(int x,int y) {
return ((x += y) >= M)?(x - M):(x);
} string dec(const string &s) {
string r = s;
int i;
for (i = r.size() - 1; i >= 0; --i) {
if (r[i] == '0') {
r[i] = '1';
}
else {
r[i] = '0';
break;
}
}
return r;
} int cal(const string &s,int k) {
int last = -1,answer = 0,i;
bool valid = true;
for (i = 0; (valid) && (i < s.size());++i) {
if (s[i] == '1') {
if (last < 0) {
answer = add(answer, dp[s.size() - 1 - i]);
}
else {
if (i - last <= k) {
valid = false;
}
if (i - last >= k) {
answer = add(answer, dp[s.size() - 1 - i]);
}
else if (last + k >= s.size()) {
answer = add(answer, 1); }
else {
answer = add(answer, dp[s.size() - 1 - last - k]); }
}
last = i;
}
}
if (valid) {
answer = add(answer, 1);
}
return answer;
} int solution(const string &S, const string &T, int K) {
// write your code here...
int i,n = T.size();
dp.resize(n + 1);
dp[0] = 1;
for (i = 1; i <= n; ++i) {
dp[i] = add(dp[i - 1], (i <= K)?1:dp[i - K - 1]); }
string temp = dec(S);
i = cal(T, K) - cal(temp, K);
return (i < 0)?(i + M):i; }

codility上的问题(15) Xi 2012的更多相关文章

  1. codility上的问题 (21) Upsilon 2012

    这是我目前最喜欢的codiltiy上的问题之一.问题描述是:给定一个整数数组A,所有的数均不相同.假设下标从0开始,找到一个数组B, 满足A[B[0]] > A[B[1]] > A[B[2 ...

  2. codility上的练习 (1)

    codility上面添加了教程.目前只有lesson 1,讲复杂度的……里面有几个题, 目前感觉题库的题简单. tasks: Frog-Jmp: 一只青蛙,要从X跳到Y或者大于等于Y的地方,每次跳的距 ...

  3. codility上的问题 (19)Sigma 2012

    题目: 像最大直方图一样给定一个数组是每个单位长度上的高度,求至少几个矩形可以拼出这个形状. 例如:给出的数组 H[0] = 8 H[1] = 8 H[2] = 5 H[3] = 7 H[4] = 9 ...

  4. codility上的问题 (23)Chi 2012

    这个题也比较有意思.意思是给定一个数组A,长度为M,里面都是正整数,代表每块地形的高度.现在要测试一种加农炮,给定一个炮弹的高度H, 如果存在最小的I,满足0 < I <  M,满足A[I ...

  5. Codility上的问题 (16) Omicron 2012

    比较无聊的题,求斐波那契数的第N^M项. f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2),结果对10000103取模. N, M在[0..10^7]之间. ...

  6. Codility上的问题 (17) PI 2012

    这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...

  7. codility上的问题(18) Rho 2012

    从正整数1开始,产生一个数列,数列中的每个数是之前出现过的任意两个数的和(可以相等),问产生正整数A,需要的数列长度至少是多少?返回这样一个最短的序列. 例如A=42 可以这样[1, 2, 3, 6, ...

  8. codility上的练习(5)

    codility出了lesson 5了. (1) 合法括号序列,包括( [ { ) ] }这6种字符的字符串,长度N在[0..200000]范围内,为其是否合法. 要求时间复杂度O(N),空间复杂度O ...

  9. codility上的问题(34) Fluorum 2014

    好久没写codility的题了.一来没时间,二来有的题目不太好分析.这个题比較有意思,我还没有给出很严格的证明.

随机推荐

  1. Swift主题色顶级解决方案一

    一.常规主题色使用点 应用在发布前都会对其主题色进行设置,以统一应用的风格(可能有多套主题).在主题色设置上有几个方面,如下: 1.TabBar部分,设置图片高亮.文本高度颜色 2.Navigatio ...

  2. hadoop源代码解读namenode高可靠:HA;web方式查看namenode下信息;dfs/data决定datanode存储位置

    点击browserFilesystem,和命令查看结果一样 当我们查看hadoop源代码时,我们看到hdfs下的hdfs-default.xml文件信息 我们查找${hadoop.tmp.dir}这是 ...

  3. 再见了acm

    2013年11月17日长沙区域赛我的最后一场区域赛. 忙碌了三年的acm要停下脚步,一时还无法接受. 这样一个结果有点无奈. 感谢队友,三年三支队伍五个队友,感谢你们.(每当写到这里时就总有点小忍不住 ...

  4. Linux如何修改SSH端口号

    SSH是什么? SSH 为 Secure Shell 由 IETF 的网络工作小组(Network Working Group)所制定: SSH 是建立在应用层和传输层基础上的一种安全协议. SSH传 ...

  5. XCode 快速注释插件

    下载VVDocumenter-Xcode这个插件 打开编译后,重启Xcode 输入///,如效果图,Window->VVDocumenter自己定制风格

  6. 开发快很重要——如果只看法语或者产品结果C++似乎很强大,但是参与这个C++的开发过程,就会感觉到这种痛苦(Google也是这个看法)

    开发快很重要——如果只看语法或者产品结果C++似乎很强大,但是参与这个C++的开发过程,就会感觉到这种痛苦,太慢了,太麻烦了,虽然在反复调试和优化之后,最后产品的结果可能还不错. Delphi的最大特 ...

  7. assert使用

    assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h> void assert( i ...

  8. sql2008r2局域网复制订阅实操

    10.129.186.37 本机 10.129.186.95 服务器 局域网环境 复制类型:事务复制 注意点:要复制的表,必须有主键,否则不可选复制表. 要点1,局域网尝试用共享的方式保存快照文件夹, ...

  9. CentOS下Samba文件服务器的安装与配置

    CentOS下Samba文件服务器的安装与配置 http://blog.csdn.net/limingzhong198/article/details/22064801 一.安装配置 1. 安装sam ...

  10. DeDeCMS中如何实现下拉菜单

    在5.7版本,已经有比较简单的方法实现下拉菜单,我们可以用它已有方法,也可以用我写的第二种方法来实现 1. 在需要下拉菜单的地方加入以下代码 <div id="navMenu" ...