查看: 2675| 回复: 6
跳转到指定楼层
上一主题 下一主题
收起左侧

[CareerCup] 5/14-5/20 CareerCup 5.3

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
Given an integer, print the next smallest and next largest number that have the same number of 1 bits in their binary representation.

上一篇:5/14-5/20 CareerCup 5.2
下一篇:5/14-5/20 CareerCup 5.4
🔗
writecoffee1 2012-6-9 20:12:24 | 只看该作者
全局:
https://github.com/writecoffee/c ... blob/master/5.3.cpp


//////////////////////////////////////////////////////////////////////////////////
// GET_NEXT
//         from the least significant digit find the first bit-1 (pos: i), and then
//        the bit-0 (pos: j), exchange w(j) and w(j-1), finally right shifting the
//        bit-1 to the rightmost positions
//
// GET_PREV
//        similar to GET_NEXT, return the "next smallest number that have the same
//        number of 1 bits in binary expression"
//
// PROOF-OF-NEXT-SMALLEST
// 1.        once we find the 'first bit-0 (pos: j)', and the modified number is
//        2^j - 2^(j-1) bigger than the original one
// 2.        restricted to the rule -- the next largest number have the same number of
//        1 bits in their binary representation, right shifting all the bit-1 to the
//        corner helps remain the "smallest" attribute
// 3.        finally, the result is up to 2^j - 2^(j-1) bigger than the original number
//////////////////////////////////////////////////////////////////////////////////
回复

使用道具 举报

🔗
paradox 2012-6-12 14:26:40 | 只看该作者
回复

使用道具 举报

🔗
285845348 2012-7-24 17:40:24 | 只看该作者
全局:
回复

使用道具 举报

🔗
chivalry 2012-7-31 22:26:28 | 只看该作者
全局:
也可以先求出整数x中1的个数为n,如果求x的最小值,把最高位设为1,然后最后n-1位为1
如果求x的最大值,从第30位开始,一共n位都设为1
回复

使用道具 举报

🔗
BinaryWitch 2012-7-31 23:39:52 | 只看该作者

发一个纯位运算的 CareerCup 5.3 题解

全局:
本帖最后由 BinaryWitch 于 2012-7-31 23:46 编辑

思路和 solution 一样 实现起来差异较大 smallest 6 行 largest 8 行可出解 只测了一般情况的 如有 bug 请指正


  1.         public static int __5_3_part1(int n) {
  2.                 int m = n & (~n << 1);        /* m 最右边的 1 就是 solution 里第一步想找的 1 他是第一个前一位是 0 的 1
  3.                 int leftOne = m & (~m + 1);   /* 取 m 最右边的 1 */
  4.                 int rightOnes = ~(n+1) & n;   /* 右边连续的 1 想把它们尽量往左移 如 solution 里的第三步
  5.                
  6.                 assert n != rightOnes: "No such number";
  7.                
  8.                 /* 下面有三种方式可以找到想把那些 1 左移几位 */

  9.                 // method 1 纯位运算 借住了求二进制中 1 的个数的经典算法
  10.                 int cnt = cntOnes( leftOne - ((rightOnes+1)<<1) );
  11.                 return n ^ leftOne ^ rightOnes | (leftOne>>1) | (rightOnes << cnt);
  12.                
  13.                 // method 2 纯数学 猥琐 短
  14.                 /*int cnt = (int) (Math.log(leftOne/(rightOnes+1)>>1) / Math.log(2) + 1e-6);
  15.                 return n ^ leftOne ^ rightOnes | (leftOne>>1) | (rightOnes << cnt);*/
  16.                
  17.                 // method 3
  18.                 /*int p = n ^ leftOne ^ rightOnes | (leftOne >> 1);
  19.                 do {
  20.                         rightOnes <<= 1;
  21.                 } while ((p & rightOnes) == 0);
  22.                 return p | (rightOnes >> 1);*/
  23.         }
  24.         
  25.         public static int __5_3_part2(int n) {
  26.                 assert ((~n+1) & n) != 0: "No such number";
  27.                
  28.                 int p = n & (~n >> 1);
  29.                 int leftOne = p & (~p + 1);
  30.                 int q = ~n + 1;
  31.                 int rightOne = q & (~q + 1);
  32.                 int condOne = n & (leftOne - rightOne);
  33.                 int cnt = cntOnes(rightOne-1);
  34.                 return n ^ leftOne ^ condOne | (leftOne << 1) | (condOne >> cnt);
  35.         }
  36.         
  37.         public static int cntOnes(int n) {
  38.                 n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
  39.                 n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
  40.                 n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
  41.                 n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
  42.                 n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
  43.                 return n;
  44.         }
复制代码

回复

使用道具 举报

🔗
285845348 2012-8-1 01:10:39 | 只看该作者
全局:
我居然用了个排序我确定位置,不厚道。。。
https://github.com/285845348/CPP/blob/master/CCP5/CCP5.3.py
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表