一、一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字
思想:
1.首先进行整体异或,那么得出的结果为两个不同数字异或的结果
2.这两个不同数字至少会有一位是不同的,我们设立一个flag从最低位进行寻找,找出第一次出现的不同位的位置
3.我们通过flag找出的那个不同位来对整个数组进行分组:一组为flag位为0的,另一位为flag位为1的
4.我们对两组分别进行异或,即可找到
下面我们来看看具体的代码:
void find_data(int arr[], int size)
{
assert(arr);
assert(size);
int res=arr[0];
int i = 1;
//step 1 整体异或
for (; i < size; i++)
{
res ^= arr[i];
}
//step 2 找标志
int flag = 1;
for (i = 0; i < size; i++)
{
if (res&(flag <<= i))
{
break;
}
}
//step3 分组
int x=0;
int y=0;
for (i = 0; i < size; i++)
{
if (flag & arr[i])
{
x ^= arr[i]; //x组里面flag位全为1,进行异或取出一个数字
}
else
{
y ^= arr[i]; //y组里面flag位全为0,进行异或取出一个数字
}
}
printf("这两个数是:%d %d", x, y);
}
int main()
{
int arr[] = { 1, 28, 3, 4, 5, 5, 4, 3, 134, 1 };
int size = sizeof(arr) / sizeof(arr[0]);
find_data(arr, size);
system("pause");
return 0;
}
二、喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水。
思想:我们要考虑一下三点
1.我们现在有20块钱,那么我们肯定会喝>20瓶,此时,我们的空瓶子数量也是有20。
2.两个可以换一瓶,那么20个空瓶子能换20/2=10个, 下一次我们再换就是10/2
3.但我们还必须得考虑假如我们有的是奇数瓶,那么在兑换的时候就会剩一个空瓶子,所以我们可以采用n%2的方法来控制,假如有偶数瓶,那么就不剩余n%2为0,奇数瓶n%2就为1.
int drink_water(int money)
{
int total= money;
int empty=money;
while (empty>1) //当空瓶子数>1才可进行兑换
{
total +=empty / 2;
empty= empty/ 2 + empty % 2;
}
return total;
}
int main()
{
int money = 20;
int total=drink_water(money);
printf("total:%d\n",total);
system("pause");
return 0;
}