#include<stdio.h>
 #include<iostream>
 #include<string>
 using namespace std;
 /*
 * 1.唯一成对的数
 法一:异或 可理解为不进位加法  ,消除重复,可找含有唯一2个重复的数(1-1000与1-1001个数异或,唯一的数被消去,剩下重复的数留下)
 (法一需知道范围数组才可用,否则法二)
 法二:开辟空间1001,出现的数字在对应空间位置加一,help[a[i]]++;
 */
 void QAQ1() {
     int n = 1001;
     int a[1001];
     for (int i = 0; i < 1000; i++) {  
         a[i] = i + 1;
     }
     a[1000] = (rand()%10 + 1);//最后一个重复的数是随机数1-1001  , rand()产生一个0-0x7fff(0-32767)的随机数,即最大是32767
    int x1 = 0;
     for (int i = 1; i <= n - 1; i++) {
         x1 = (x1 ^ i);//异或
     }
     for (int i = 1; i < n ; i++) {
         x1 = x1 ^ a[i];//不用开辟空间
     }
     cout << x1 << endl;
     //开辟空间
     /*cout << ---------一条优美的分界线----------- << endl;
     int help[1001];
     for(int i = 0;i < n;i++){
     help[a[i]]++;
     }
     for(int i = 0;i < n;i++){
     if(help[i] == 2)
     cout << i << endl;
     }
     */
 }
/*求二进制中1的个数
 法一:1左移和N与运算相同则加一 ,判读二进制每一位上是不是1
 法二:(x-1)&x 效果消掉低位的1变成0      【11000 - 1 = 10111   , 11000 & 10111 = 10000 】
/括:用一条语句判读整数是不是2的整数次方 if((N-1)&N == 0)
 */
 void QAQ2() {
     int N;
     cin >> N;//输入od十进制转二进制ob  ????????????
     //-----------------转二进制
     int count = 0;
     //法一
     for (int i = 0;i < 32;i++) {  //32位
         if ((N & (1 << i)) == (1 << i)) {//其他位位0,且的性质消掉,等效把1移动从1-32位依次比较  <<优先级大于==,加括号
             count++;
         }
     }
     /*
     //法二
     while (N != 0) {
         N = ((N - 1) & N);
         count++;
     }
     */
     cout << count << endl;
 }
 /*位运算
 * 整数的奇偶位交换(和010101010101010101 。。。32位&运算后得到保留奇数位值,同理101010101010。。。32位得到偶数位值)
     奇左移一位,偶右移一位,两个再异或得到奇偶位交换效果(提取奇数放在偶数位上,提取偶数放在奇数位上)
 */
 int change(int i) {
     
     
     int even = i & 0b01010101010101010101010101010101;  //偶
     int odd = i & 0b10101010101010101010101010101010;//奇
     /*
     int even = i & 0xaaaaaaaa;       //***************************0b二进制,0d十进制,0x十六进制
     int odd = i & 0x55555555;
     */
     /*
     表示2
     int even = i&0xaaaaaaaa;//和1010 1010 1010 。。。。运算出偶数位  ,Java中a 1010
     int odd = i&0x55555555;//
     */
     return (odd>>1)^(even<<1);  //10 <--> 01    ,(odd>>1)+(even<<1)也行
 }
 void QAQ3() {
     int a,b;
     cin >> a;
     b = change(a);
     cout << b << endl;
 }
 /*介于0-1之间的小数可被32位以内二进制精确表示则转换,否则输出ERROR  0.32位(加0.共34位)
 默认double    乘积取整法
 */
 void QAQ4() {
     double num = 0.625;
     string sb = "0.";
     while (num > 0) {
         double r = num * 2;
         if (r >= 1) {
             sb.append("1");//加1  append在字符串末尾加"..."
             num = r - 1;
         }
         else {
             sb.append("0");
             num = r;
         }
         if (sb.length() > 34) {
             cout << "ERROR" << endl;
             return;
         }
         
     }
     cout << sb << endl;
 }
 /*数组中一个数只出现了1次,其他数出现了k次,请输出这个数(练习进制)   简单解法创一个数组对应位加一,最终判断数组中值为1的即出现1次
 2个相同的2进制数做加法结果为0,10个相同的10进制数做加法结果为0
 **即k个相同的k进制数做加法结果为0    ,输出结果k进制转十进制手工取余法  //java中有现成的
 */
 void QAQ5() {//?????????????????1.9课未完成
     int a[] = { 2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0 };
     int len = (sizeof(a)/4);
     char kRadix[100][100];  //保存在二维数组中成3进制并翻转,然后转为字符数组,第一位为低位9 -》 001
     int k = 3;
     int maxlen = 0;
 }
 /*第二章 递归   学会评估算法性能   //练习策略循环改递归
  
 *找重复     n阶乘  n*(n-1)   n-1的阶乘是原问题的重复,但规模更小-子问题
 *找变化        变化的量应该作为参数
 *找边界  出口  n = 1时
 */
int jiecheng(int n){
     if (n == 1) {
         return 1;
     }
     return n * jiecheng(n - 1);//委托出去的部分收回
 }
void QAQ6() {
     cout << jiecheng(5) << endl;
 }
int main() {
   
    
     
     
     return 0;
 }










