uva 11645 Bits
2013-01-14 23:03
302 查看
uva 11645 Bits
题目描述:一个数n的二进制表示中连续的11的个数记为f(n),例如f(111) = 2, f(1111) = 3,先给定n求ans = sum (f(i)) 0=<i <= n;解决办法:逐位确定
举例说明:n = 1111, x1 = 11**, x2 = *11*, x3 = **11
所以答案可以分成如下3个部分,即前两位是11的个数,中间两位是11的个数,后两位是11的个数。
首先对于前两位是11的个数,也即x1情况下,此时,满足条件的数由后两位确定,所以一共有4个(0~11)
然后对于中间两位是11的个数,这个时候后面的取值受限于第一位,
但是我们可以分成两种情况来计算,前面的部分是小于n的对应位的也即取0,此时后面1位有2中取值方式,故有1*2个数;前面的部分刚好与n的对应部分相等即取1,此时后面只有0~1(1为n的最后几位的值)所以此时有:1 + 1个数, 此种情况下共有4个
最后对于后两位是11的个数,这个时候只取决于n的前两位的取值,所以有4种
综上3种情况,共有4+4+4 = 12
再看对于n = 11011:
同样可以分成x1 = 11***, x2 = *11**,x3 = **11*, x4 = ***11
计算x1:满足x1的情况只有011 + 1种,即:4种
计算x2: 满足x2的情况可以分成,前面的部分小于n对应位,此时只能取0,后面有2^2种取法,所以有4种,而对于前面部分等于n对应位,此时得到的数已经超过了11011所以此时是不存在的,故满足x2的共有4种
计算x3:同情况2,拆分成两个部分,前面两位小于11011的前两位,此时前面有3(0~11-1)种取法,后面可以取2^1种,故有3*2 = 6种;
前面两位与11011的前两位相等,由于已经超过原数,不存在
计算x4:由于最后两位和原数的最后两位一样,所以有110 + 1种取法,故而有7种取法
综上4种情况共有4 + 4 + 6 + 7 = 21。
归纳起来:对于位置i和i-1如果都为1,那么可以分成两部分:
l * 2^(i - 1) l = n>>i;
如果原数的i和i-1位都是1,那么返回,r + 1, r = n%(1<<(i-1));否则返回0
然后就是大数,只需要大数加。
最近写代码写的比较少,思维比较卡,代码写的比较搓。。。。。。在UVA上跑了,0.008s。。。。。。再优化一下,说不定可以跑到第一。。。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; LL f[65]; const int base = 10000; class bigInt{ private: int s, num[10]; public: bigInt(); bigInt(LL ); friend bigInt operator+(const bigInt&, const bigInt &); void print()const ; }; bigInt::bigInt(){ s = 1; memset(num, 0, sizeof(num)); } bigInt::bigInt(LL x){ s = 0; memset(num, 0, sizeof(num)); if(x==0) s = 1; while(x){ num[s ++] = x%base; x = x/base; } } bigInt operator+(const bigInt &op1, const bigInt &op2){ bigInt r; r.s = op1.s > op2.s ? op1.s : op2.s; for(int i = 0; i < r.s; i ++){ r.num[i] = r.num[i] + op1.num[i] + op2.num[i]; r.num[i + 1] = r.num[i]/base; r.num[i] = r.num[i]%base; } while(r.num[r.s]){ r.num[r.s + 1] = r.num[r.s]/base; r.num[r.s] = r.num[r.s]%base; r.s ++; } return r; } void bigInt::print()const{ printf("%d", num[s - 1]); for(int i = s - 2; i >= 0; i --){ printf("%04d", num[i]); } printf("\n"); } void init(){ f[0] = 1; for(int i = 1; i != 64; i ++){ f[i] = f[i - 1] + f[i - 1]; } } int main(){ init(); int cas = 0; LL K, left, right; bigInt ans; ios::sync_with_stdio(false); while(cin>>K, K >= 0){ int i; for(i = 63 ; i >= 0; i --){ if(K&f[i]){ break; } } left = 0, right = K; ans = 0; if(K&f[i]){ right = K - f[i]; } if(K&f[i - 1]){ right = right - f[i - 1]; } if((K&f[i]) && (K&f[i-1])){ ans = right + 1; } i --; while(i > 0){ left = left + left; left = left + ((K>>(i + 1))&1); if(K&f[i - 1]){ right = right - f[i - 1]; } if((K&f[i]) && (K&f[i-1]) ){ ans = ans + left * f[i-1] + right + 1; } else{ ans = ans + left * f[i-1]; } i --; } printf("Case %d: ", ++cas); ans.print(); } return 0; }
相关文章推荐
- UVA 11645 - Bits(数论+计数问题)
- uva 11645 - Bits(计数问题+高精度)
- UVA - 11645 Bits
- UVA11645 Bits【位运算+大数】
- UVA 11645 Bits
- uva11645 - Bits 统计 巧妙的大数
- UVa 11645 Bits(计数原理+高精度)
- Uva 11645 - Bits 解题报告(递推+大数)
- UVA11645:Bits
- UVa11645 - Bits(递推+高精度)
- uva11645 Bits(数位统计)
- Bits Equalizer UVA - 12545
- uva11645
- Bits Equalizer UVA - 12545
- UVa 446 - Kibbles "n" Bits "n" Bits "n" Bits
- UVA_446_Kibbles "n" Bits "n" Bits "n" Bits
- uva 11645 求连续的11有多少个
- UVA - 11645
- UVA 10061
- Uva11324——最大团