zoukankan      html  css  js  c++  java
  • codility上的问题(15) Xi 2012

    进入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;
        
     }
    



  • 相关阅读:
    selenium屏蔽浏览器检测
    cookies字符串转化为字典
    python压缩图片大小
    python异步爬虫aiohttp
    python通过命令行接收参数
    hustoj实现远程判题的两种方案
    SqlLocalDB工具的一些有趣发现
    Chrome中编译安装vue-devtools插件
    用友政务表格技术应用开发实践:预算一体化产品核心功能搭建
    企业表格技术应用开发案例大赛圆满落幕!
  • 原文地址:https://www.cnblogs.com/riskyer/p/3271271.html
Copyright © 2011-2022 走看看