C语言程序设计 | 单身狗题目讲解

题目要求

img

思路

第一种思路呢就是暴力求解。思路就不用多讲,代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void find_num(int* a, int num)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num; i++)
	{
		int sum = 0;
		for (j = 0; j < num; j++)
		{
			//不与自己比较
			if (i != j)
			{
				//如果相同,则不是我们找的数字
				if (((a[i]) ^ (a[j])) == 0)
					;
				//否则可能是我们要找的数字
				else
					sum += 1;
			}
		}
		if (sum == num-1)
		{
			printf("%d ", a[i]);
		}
	}
}
void input_data(int* a, int num)
{
	int i = 0;
	for (i = 0; i < num; i++)
	{
		scanf("%d", &a[i]);
	}
}
int main()
{
	int a[100] = {0};
	int n = 0;
	scanf("%d", &n);
	input_data(a, n);
	find_num(a, n);
	return 0;
}

第二种就是应用C语言操作符异或来求得两个单身狗。

首先要知道的是两个相同的数异或得0,假设我们现在有这样的一个数组。

int arr[5]={1,2,3,1,2};

令这个数组从首元素开始遍历异或,1异或2,再异或3,再异或1,再异或2,得出的结果就是3,就能找出这样的一个单身狗。

整个流程如下图所示:

img

int main()
{
	int arr[5] = { 1,2,3,1,2 };
	int i = 0;
	int dog = 0;
	for (i = 0; i < 5; i++)
	{
		dog ^= arr[i];
	}
	printf("%d ", dog);
	return 0;
}

那么我们就知道在一个数组中找一个单身狗,就是通过异或来获得的,那么有两个单身狗怎么做呢?

假设现在有这么一个数组

int arr[6]={1,2,3,4,1,2};

在对整个数组异或之后可以得出结果是3^4

img

可以看到3的这个单身狗二进制的最后一位是1,

4的这个单身二进制的最后一位是0,那么我们就可以通过这个二进制位来对这个数组进行分组。

分成这样的两组:

img

然后再分别在这两个组中找出自己组的单身,例如组1找的单身狗是3,组2找的单身狗是4。所以代码就可以这样写:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int arr[6] = { 1,2,3,4,1,2 };
	int ret = 0;
	int i = 0;
	int dog1 = 0;
	int dog2 = 0;
	//遍历异或整个数组,得出两个不同数异或的结果
	for (i = 0; i < 6; i++)
	{
		ret ^= arr[i];
	}
	//确定得出的结果最右边的1的位置
	int pos = 0;
	for (pos = 0; pos < 32; pos++)
	{
		if (((ret >> pos) & 1) == 1)
		{
			break;
		}
	}
	//分组
	for (i = 0; i < 6; i++)
	{
		if (((arr[i] >> pos) & 1) == 1)
		{
			dog1 ^= arr[i];
		}
		else
		{
			dog2 ^= arr[i];
		}
	}
	printf("%d %d ", dog1, dog2);
	return 0;
}

这里考察的是异或的运用,以及0异或任何数就得任何数的知识点(个人认为)。

这里的代码呢写得不是很高级,如果觉得写得不好可以提出批评。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值