欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

算法训练 C语言 二进制数数(给定L,R。统计[L,R]区间内...)

程序员文章站 2022-07-15 09:47:13
...

问题描述:

给定L,R。统计[L,R]区间内的所有数在二进制下包含的"1"的个数之和。如5的二进制位101,包含2个"1"。

输入格式:
       第一行包含2个数L,R。

输出格式:
       一个数S,表示[L,R]区间内的所有数在二进制下包含的"1"的个数之和。

样例输入:
2 3

样例输出:
3

数据规模和约定:
L<=R<=100000;

思路:本题由于是要统计1的个数,那么采取数组存储二进制数的每一位比较好,也就是需要一步一步的统计0和1,因此需要灵活变换一下十进制转二进制的方法。然后再遍历统计好的数组找1即可。

代码:

#include<stdio.h>
int x,i,j,t,k,count;//转换函数里用的到,定义在外边 
int a[20];//由于用的是把二进制数分为一个个的0或1,所以定义数组存储 
void change(int x);//十转二函数 

int main()
{
	int l,r;
	scanf("%d%d",&l,&r);
	count=0;//用来记录1的个数 
	for(k=l;k<=r;k++)
	{
		change(k);//话不多说,直接去转 
		for(j=i-1;j>=0;j--)//这时已经将当前k的二进制数用数组从后往前的存储好了 
		{
			if(a[j]==1)//如果找到1,则统计数+1 
			{
				count++;
			}
		}
	}
	printf("%d",count);
	return 0;
}

void change(int x)
{
	for(i=0;i<20;i++)//每次进入一个新数,把数组初始化一下 
	{
		a[i]=0;
	}
	i=0;//表示从a[0]开始存储 
	while(x>0)//就是限制一下循环 
	{
		t=x%2;//先除以2取余 
		a[i]=t;//记录余数 
		i++;//进行数组的下一位 
		x=x/2;//更新x值 
	}
}

测试:
算法训练 C语言 二进制数数(给定L,R。统计[L,R]区间内...)
总结:初次拿到这题的思路是想着把二进制数用几千几百几十几的那样求,然后除以多少再模十把每一位表示出来,之后发现数规模大起来了,表示各个位数就得用十几个未知数,复杂的很。写在文章里的这个思路相对来说要简洁的多,如有不正好之处,恳请评论下,我一定改进。