• 不用四则运算符求A+B问题


    刚入门c++,刚打完A+B的程序代码(可能算不上程序-_-!!!)就被学长调戏着问会不会能不能不用+号做A+B问题,当时一脸懵逼,以为有什么神奇的函数和算法,或者什么不入流的赖皮代码,今天偶然学了一下,也来螺旋升天秀一波!

    思路流程

    这是一道使用位运算的题目,很好,我们可以直接使用二进制来思考,因为c++是支持直接把数当二进制使用的。那么对于每一个位,都只有三种情况:

    1. 0+0=0;
    2. 1+0=1;
    3. 1+1=(1)0; 
      第一种和第二种是很简单的,因为没有进位,我们可以直接使用或运算:|,两者不同(1+0=1)为真,两者相同为假(0+0=0)。因为不存在1+1的进位情况。 
      第三种情况和第一种情况相比,是这题的难点:它们的结果都是0,但显然,它们对答案的影响完全不同! 
      所以,我在想有没有什么操作,可以记录下两个数都为1的情况。好在,有这样一个东西:&,符号与,意思是按二进制,两个位同真为真,其他为假。 
      那么,我们就可以得到一个新的二进制数,它的1表示进位,0表示没有进位。 
      例如,9(1001)+3(11):

     

    进位了,之后该如何呢? 
    模仿加法的操作,我们相当于让原本加数的下一位+1,相当于,我们多了一个新的加数,“进位数”。所以我们需要两个东西:原本两个数相加的结果(没有进位),以及进位数。 
    第一个,刚好又有一个工具:异或,^,它的作用是安位,两位相同取0(0+0=0||1+1=0),否则取1(1+0=1)。 
    第二个,我们刚好有另一个工具,位运算: 
    a=< < k的意思是,把a的二进制全部左移k位,相当于乘以了2k2k; 
    我们用它,就可以很方便的解决这个问题了!进位数左移一位,现在把它和原来的结果相加就可以了! 
    最后一个问题:这个时候,相加仍可能进位,能进位怎么相加呢?我们必须找出不进位的结果,所以我们不断重复前两个动作,直至可以不进位相加为止。

     

    代码如下:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 int main()
     7 {
     8     int a,b,c;
     9     scanf("%d%d",&a,&b);
    10     c=a&b;
    11     while(c!=0)
    12     {
    13         a=a^b;
    14         b=c<<1;
    15         c=a&b;
    16     }
    17     printf("%d",a|b);
    18     return 0;
    19 }

    顺便说一下,这个操作的时间复杂度是O(logn),所以除了花式秀操作,并没有什么卵用,但位运算的思想和这几个运算符,在后面会经常用到,所以请熟练它们。 

    这个可以很好的加强你对位运算的理解,所以这也不失为一道不错的题

  • 相关阅读:
    Office转SWF的一些感想(Office2007和Office2010)
    数据库字段为日期类型时
    C#实现office文档转换为PDF格式
    C#.net word excel powerpoint (ppt) 转换成 pdf 文件
    Servlet基础
    Android加速度传感器实现“摇一摇”,带手机振动
    android完全退出应用程序
    【安卓笔记】作为内部类的广播接收者
    Android中使用广播机制退出多个Activity
    [Android] ImageView.ScaleType设置图解
  • 原文地址:https://www.cnblogs.com/genius777/p/8470116.html
Copyright © 2020-2023  润新知