蓝桥杯刷题第二天

1.找出唯二出现一次的数
唯二
思路:
如果把所有的数组全部异或起来就有一个数就是唯二的2个数字异或起来;
比如1 2 3 3 4 4;
异或到最后就得出的数字是1 2 ;
这个数字必有一个地方是1(二进制下);一个数在这个地方是1,另一个数在这个地方是0;比如k位上
这样我们就可以把这些数字分成2个集合:
一每个集合都异或起来,那么里面成对的变为0,那么剩下的就是那个数;
代码:

public static int[] findNumsAppearOnce(int[] nums) {
    
    
       int sum=0;
       for(int i=0;i<nums.length;++i)
       {
    
    
    	   sum^=nums[i];//将所有元素集合起来
       }
       int k=0;
       while((sum>>k&1)==0) k++;
       int x=0;
       for(int i=0;i<nums.length;++i)
       {
    
    
    	   if(((nums[i]>>k)&1)==1)
    	   {
    
    
    		   x^=nums[i];
    	   }
       }
    
      int  y=x^sum;
 
      int []p= {
    
    x,y};
      return p;
       
    }

题目:
不用加减乘除计算a+b;
代码:
思路:
我们把加法拆分不进位加法和进位加法,加法满足结合律:
不进位的话用异或来进行加法:
3(11)
2(01)
异或后变为
(10)表示不进位加法:
进位的话要用到&进行计算;
&之后的位数就是进位,往左边移动一个位(向高位进位)
代码:

/*
3 4
11
10
01
异或是减法吗:
4 5
10
11
01
4 6
10
11
 





*/
#include <iostream>
using namespace std;
int main()
{
    
    
	int num1,num2;
	cin>>num1>>num2;
	while(num2!=0)//如果进位还存在的话
	{
    
    
		int sum=num1^num2;//不进位加法先计算一下
		int carry=(num1&num2)<<1//&出来的话就是需要进位加法;
		num1=sum;//num1赋值为sum
		num2=carry;//num2赋值为carry
	}
	cout<<num1;
 } 

t题目:
64位整数乘法;
输出ab%p;
我们可以发现 2
7可以看成这样
7是111
21 2的0次方 2
2
12的2次方 4
2
1*2的3次方 16
代码:

/*输入数据
如果这个位置是1的话就用这个位数代表的2进制和要乘法的数字相乘
不断到结尾,加起来总和就是
*/
#include  <iostream>
using namespace std;
int main()
{
    
    
	long long a,b,p,res=0;
	cin>>a>>b>>p;
	while(b)
	{
    
    
		if(b&1) res=(res+a)%p;//是一的话就加上2的该位次幂,只有是1就加上去 
		b>>=1;//将被乘数不断左移看看这个位置上有没有1; 
		a=(2*a)%p;//没移动一次位次幂就要乘以2 第一次是2,移动一次后变成了2*2=4,继续移动就是2*2*2=8; 
	}
	
	cout<<res<<endl;
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/m0_51373056/article/details/111322507