异或 问题
来源:互联网 发布:php 发邮件类 编辑:程序博客网 时间:2024/05/22 14:10
问题定义:有2n+1个数,只有一个单着,别的都是成对的,找出这个单着的数。比如:2 1 3 2 1。3是答案。
思路一:暴力搜索——每个数都和其他数比较,找不到相同的,就得到了结果。时间复杂度为o(n2)
思路二:排序搜索——先给序列排个序,之后从前往后一对一对的找,直到不是成对的为止。时间复杂度,怎么也得o(nlgn)
思路三:异或计算,一趟搞定。时间复杂度o(n)
直接看思路三:
原理:异或操作(^)——(对于位操作)相同为0,相异为1.比如:1^0 = 1, 1 ^1=0
这样:
- 两个相同的数异或就为0
- 任何数和0异或为自己(转化到位。1^0 = 1, 0 ^0=0)
例如:5 ^ 5 = 0
5 ^ 0 = 5
对于本题:2 1 3 2 1,都异或一下:相同的(2^2,1^1) 为0,剩下的3和0异或为自身3。(注:异或具有交换律)
代码:
#include <stdio.h>int main(){ int a[5] = {2, 1, 3, 2, 1}; int aim = a[0]; for(i = 1; i < 5; i++) { aim = aim ^ a[i]; } printf("Result:", aim); return 0;}
异或在这方面挺好,再来个应用:
不用第三个数直接交换两个数:#include <stdio.h>void swap(int *a, int *b){ *a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b;}int main(){ int a=3, b=5; swap(&a, &b); printf("%d\n%d", a, b); return 0;}
转自:jihite
hihoCoder #1509 : 异或排序
描述
给定一个长度为 n 的非负整数序列 a[1..n]
你需要求有多少个非负整数 S 满足以下两个条件:
(1).0 ≤ S < 260
(2).对于所有 1 ≤ i < n ,有 (a[i] xor S) ≤ (a[i+1] xor S)题解:(转自:伪·ACMer)
由于每一个数都有一个二进制表示,由数论知识我们知道比较两个数是从高位开始比较的,当比较到某一位发现一个数该位为1而另一个数该位为0时就知道前面那个数一定比后面那个要大,而再考虑异或的性质:
0 Xor 1 = 1
1 XOR 1 = 0
0 XOR 0 = 1
假设我们有两个数x,y,不妨设x>y,那么存在第i位使得x与y在更高的位都相等但是x在该位为1而y在该位为0,由于 1 XOR 1 = 0, 0 XOR 1 = 1,那么假若存在S,只要S在第i位为1,就能使得 (x XOR S) <= (y XOR S)
反正只要该位符合题意就好,其他位是任意的,显然这个任意的数目就是我们要求的了0。0思路大体也出来的
先生成一个S[60]的数组,扫描一遍,检索两个数是小大还是大小关系,小大关系的话在那个位置0,大小关系的话在那个位置成1,注意如果那位本来有数的话要看看是否一致,不一致说明这个东西他不存在
最后看看有多少个位置是没有被固定的,那么2的那个那个数目次方就是所求。#include <iostream>#include <stdio.h>#include <string.h>#define LL long longusing namespace std;const int ma=65;LL num[ma],pow[ma];int flag[ma];LL quick_pow(int x) ///计算2^k(2的k次方){ if(pow[x]!=0) return pow[x]; return pow[x]=quick_pow(x/2)*quick_pow(x-x/2);}int fi(LL x){ int i; for(i=60-1;i>=0;--i) if(x>=quick_pow(i)) break; return i;}int main(){ memset(pow,0,sizeof(pow)); pow[0]=1; pow[1]=2; quick_pow(60); int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%lld",&num[i]); memset(flag,-1,sizeof(flag)); LL cnt; int fg,k; for(int i=1;i<n;++i) { cnt=num[i]^num[i+1]; fg=(num[i]>num[i+1]); k=fi(cnt); if(k==-1) continue; if(flag[k]==-1) flag[k]=fg; else if(flag[k]!=fg) { printf("0\n"); return 0; } } k=0; for(int i=0;i<60;++i) if(flag[i]==-1) k++; printf("%lld\n",quick_pow(k)); return 0;}
- 异或问题
- hdu2095异或问题
- HZAU 异或问题
- 异或 问题
- 异或问题(java)
- 正整数异或值问题
- 异或值问题III
- 正整数异或值问题
- JAVA基础-异或问题
- java中的异或问题
- BP神经网络-异或问题
- 汉字字符串异或加密问题
- 关于异或交换数字的问题
- 异或巧解筷子问题
- CSDN 正整数异或值问题
- 关于异或运算的一个问题
- 基于BP网络解决异或问题
- POJ 1830 开关问题(异或版高斯消元)
- 教你如何配置Spring Boot的properties文件
- nginx安装流程
- svm 相关整理笔记
- 使用grep搜索多个单词或字串
- Java保留小数点的几种方法
- 异或 问题
- BZOJ 3328: PYXFIB 二项式定理 原根 构造
- VS2015打开特定项目就崩溃
- 线性回归
- <select>设置css height兼容性,兼容FF/IE/Safari/Chrome...
- 51nod 1799 二分答案
- MySQL慢查询日志
- Java数据库数据比较问题
- 纯win32实现录音器并播放功能