题目大意:求出一个数比给定的数D大并且此数的二进制中的1的个数再s1,s2之间.
思路:如果直接通过D+1向后暴力的话,必定时超时的,因为输入为300000组,如果给个2^31的D,s1=1,s2=1,那么找每个
二进制值0.1的个数就会执行30次,并且还有循环找数的过程所以会超时.不能直接对数就行操作,那么可以对当前的2进制
的0.1进行操作,当D+1的二进制中的1>s2时,应该将多的1,变为0,我们可以通过(D+1)+(1<<i )(i为再arr中1的位置)用进位
相反(D+1)<s1我们通过增1来补.
(必须用%I64d)
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<map> #include<cmath> #include<algorithm> #include<queue> #define ll __int64 #define inf 2147483647 using namespace std; ll arr[1000000],t; ll lowbit(ll n) { ll s=0;t=0; while(n) { arr[t++]=n&1; if( (n&1)==1) s++; n>>=1; } return s; } int main() { ll m,i,j,s1,s2,cla,d,tmp; scanf("%d",&cla); for(int gr=1; gr<=cla; gr++) { scanf("%I64d%I64d%I64d",&d,&s1,&s2); d++; while(1) { m=lowbit(d); printf("%d\n",m); if(m<s1) { for(i=0; i<t; i++) { if(arr[i]==0) { d+=(1<<i); break; } } } else if(m>s2) { for(i=0;i<t;i++) { if(arr[i]==1) { d+=(1<<i); break; } } } else break; } printf("Case #%d: %I64d\n",gr,d); } }