算法很美之位运算

第一篇 位运算

题目1 : Exam07_TwoSingleNumbers

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

一个整型数组里除了两个数字(互不相同)之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
输入

第一行:数组的长度N(1<n<100000)
第二行:N个整数,空格隔开
输出

只出现了1次的那两个数,小的在前大的在后,空格隔开
样例输入

10
5 5 6 7 9 9 7 3 3 2 

样例输出

2 6

附上accep代码

// c语言实现

#include<stdio.h>

main()
{
	int n,i,a[100000],j;
	while(scanf("%d",&n)!=EOF)
	{
		//	输入数据
		for(i=0;i<n;i++)
			scanf("%d",&a[i]);
		// 对数组进行排序 从小到大
		for(i=n-1;i>0;i--)
			for(j=0;j<i;j++)
			{
				//	交换两个数
				if(a[j]>a[j+1])
				{
					a[j]^=a[j+1];
					a[j+1]^=a[j];
					a[j]^=a[j+1];
				}
			}
		// 如果下一个数和这个数相等,自动跳到下下一个数:
		// 如果下一个数和这个数不相等,输出该数:
		for(i=0;i<n;i++)
			if(a[i]==a[i+1])
				i++;
			else printf("%d ",a[i]);		
			
	}
	return 0;
}

题目2 : Exam08_ChangeBit

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

给定两个整数A和B,需要改变几个二进制位才能将A转为B。
输入

1行:A和B,空格隔开
输出

需要改变的位数
样例输入

10 8

样例输出

1

附上accep代码
// 方法一


#include<stdio.h>
// 将a,b两个数先异或 赋值给a  化a为二进制  二进制中一的个数即为答案  
int ej(int a)
{
	int i=0,s=0;
	while(a!=0)
	{
		i=a%2;
		if(i==1)
			s++;
		a=a/2;
	}
	return s; 
}
main()
{
	int a,b;
	scanf("%d%d",&a,&b);
	a=a^b;
	printf("%d",ej(a));
	return 0;
} 

// 方法二


#include<stdio.h>
// 将a,b两个数均化为二进制,比较不同的位数即为答案
int a1[10],b1[10];

void ej(int a,int b)
{
	int i=0,j=0,k,s=0;
	while(a!=0)
	{
		a1[i++]=a%2;
		a/=2;
	}
	j=i;
	i=0;
	while(b!=0)
	{
		b1[i++]=b%2;
		b/=2;
	}
	if(i>j)
		for(k=0;k<i;k++)
		{
			if(a1[k]!=b1[k])
				s++;
		}
	else
		for(k=0;k<j;k++)
		{
			if(a1[k]!=b1[k])
				s++;
		}  
	printf("%d\n",s);
}

main()
{
	int a,b;
	while(scanf("%d %d",&a,&b)!=EOF)
	{
		ej(a,b);
	}
	return 0;
}

题目3 : Exam09_StrangeDonate

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

地产大亨Q先生临终的遗愿是:拿出100万元给X社区的居民抽奖,以稍慰藉心中愧疚。
麻烦的是,他有个很奇怪的要求:

  1. 100万元必须被正好分成若干份(不能剩余)。每份必须是7的若干次方元。比如:1元, 7元,49元,343元,…

  2. 相同金额的份数不能超过5份。

  3. 在满足上述要求的情况下,分成的份数越多越好!

请你帮忙计算一下,最多可以分为多少份?
输入

固定输入:1000000
输出

最多可以分为多少份
样例输入

1000000

样例输出

附上accep代码

#include<stdio.h>
//	直接暴力求解
/*
7的次方能有多少啊?不超过100万的一共就那么几个,每个的取值从0到5,
组合起来也没有多少啊,看看哪个组合刚好凑成100万不就行了。
    如果嫌找出最多的那个组合费事,把所有凑成100万的输出不就行了?我就不信,
能凑成100万的情况会有那么多吗?应该屈指可数吧!    
*/
main()
{
	int a[9]={1,7,49,343,2401,16807,117649,823543,5764801};
	int i0,i1,i2,i3,i4,i5,i6,i7,i8;
	for(i0=0;i0<6;i0++)
	for(i1=0;i1<6;i1++)
	for(i2=0;i2<6;i2++)
	for(i3=0;i3<6;i3++)
	for(i4=0;i4<6;i4++)
	for(i5=0;i5<6;i5++)
	for(i6=0;i6<6;i6++)
	for(i7=0;i7<6;i7++)
	for(i8=0;i8<6;i8++)
	if(i0*a[0]+i1*a[1]+i2*a[2]+i3*a[3]+i4*a[4]+i5*a[5]+i6*a[6]+i7*a[7]+i8*a[8]==1000000)
		printf("%d\n",i0+i1+i2+i3+i4+i5+i6+i7+i8);
	return 0;
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值