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

问题描述:

给定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值 
	}
}

测试:
在这里插入图片描述
总结:初次拿到这题的思路是想着把二进制数用几千几百几十几的那样求,然后除以多少再模十把每一位表示出来,之后发现数规模大起来了,表示各个位数就得用十几个未知数,复杂的很。写在文章里的这个思路相对来说要简洁的多,如有不正好之处,恳请评论下,我一定改进。

发布了6 篇原创文章 · 获赞 3 · 访问量 556

猜你喜欢

转载自blog.csdn.net/qq_45556278/article/details/105010806