Chance Gym - 101086L——二进制,素数

19 篇文章 1 订阅

原题链接:https://codeforces.com/gym/1010

After Noura's brother, Tamim, finished his junior training, coach Fegla was impressed with his progress. He told Noura that if Tamim would solve the following problem in SCPC2015 and yet does not qualify to the ACPC2015, he will give him a chance to participate unofficially in it.

The problem goes as follows:

Given L and R, how many integers between them have a prime number of ones in their binary representation?

Can you help Tamim participate in the ACPC2015?

Input

The first line of input contains an integer T (1 ≤ T ≤ 105), the number of test cases.

Each test case will consist of two space - separated integers: L and R (0 ≤ L ≤ R ≤ 105).

Output

For each test case, print the number of integers between L and R that have a prime number of ones in their binary representation.

题意:

不太好读懂题目意思(手动滑稽,单靠英语的字面意思不是很好理解)。

给定一个区间[l, r],区间里面的每一个整数,它的二进制形式有k个1,如果k是素数的话,那么这个数满足条件,求区间中有多少个整数满足这个条件。

注意:

判断素数的时候,只要判断到1——100以内的素数就可以了。因为,二进制形式不可能有100个1吧,如果有100个1,这个数得到2的100次方了,这是一个多么大的数。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

int b[N];
//判断素数
bool prime(int n)
{

          int root = sqrt(n) + 1;
          for(int i=2; i < root; i++)
          {
               if(n % i ==0)
                    return 0;
          }
     return 1;
}

//得到二进制形式有多少个1
int bi(unsigned int n)
{
    unsigned int c =0 ; // 计数器
    for (c =0; n; n >>=1) // 循环移位
        c += n &1 ; // 如果当前位是1,则计数器加1
    return c ;
}

bool is_prime[200];
int main()
{
     for(int i=2; i<=150; i++)
     {
          is_prime[i] = prime(i);
     }
     is_prime[1] = 0;
     is_prime[0] = 0;
     for(int i = 0; i<N; i++  )
     {
          int temp = bi(i);
          if( is_prime[temp]  )
          {
               b[i] = b[i-1] + 1;
          }
          else
          {
               b[i] = b[i-1];
          }
     }
     int T;
     cin>>T;
     while(T--)
     {
          int l, r;
          cin>>l>>r;
          int ans = b[r] - b[l];
          int temp = bi(l);
          if(is_prime[temp] )
               ans++;

          cout<<ans<<endl;
     }
     return 0;


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值