zoukankan      html  css  js  c++  java
  • ~按位取反

    ~是按位取反运算符

    这里先说一下二进制在内存的存储:二进制数在内存中以补码的形式存储

    另外,正数的原码、补码和反码都相同

    负数的反码与原码符号位相同,数值为取反;补码是在反码的基础上加1

    比如:

    ~9的计算步骤:

    转二进制:0 1001

    计算补码:0 1001

    按位取反:1 0110

    转为原码:1 0110

    按位取反:1 1001   反码

    末位加一:1 1010   补码

    符号位为1是负数,即-10

    规律:~x=-(x+1);

    因此,t=~9(1001)并不能输出6(0110),而是-10;

    牛客网暑假训练第七场A题:

    链接:https://www.nowcoder.com/acm/contest/145/A
    来源:牛客网

    Minimum Cost Perfect Matching
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 262144K,其他语言524288K
    Special Judge, 64bit IO Format: %lld

    题目描述

    You have a complete bipartite graph where each part contains exactly n nodes, numbered from 0 to n - 1 inclusive.

    The weight of the edge connecting two vertices with numbers x and y is (bitwise AND).

    Your task is to find a minimum cost perfect matching of the graph, i.e. each vertex on the left side matches with exactly one vertex on the right side and vice versa. The cost of a matching is the sum of cost of the edges in the matching.

    denotes the bitwise AND operator. If you're not familiar with it, see {https://en.wikipedia.org/wiki/Bitwise_operation#AND}.

    输入描述:

    The input contains a single integer n (1 ≤ n ≤ 5 * 10
    5
    ).

    输出描述:

    Output n space-separated integers, where the i-th integer denotes p
    i
     (0 ≤ p
    i
     ≤ n - 1, the number of the vertex in the right part that is matched with the vertex numbered i in the left part. All p
    i
     should be distinct.

    Your answer is correct if and only if it is a perfect matching of the graph with minimal cost. If there are multiple solutions, you may output any of them.
    示例1

    输入

    3

    输出

    0 2 1
    题意:给你一个n,让你输出一行与1~n-1 &起来 的值的和最小,如:0 2 1 (0&0+1&2+2&1=0
     

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define mod 1000000007
    const int N=5e+5;
    int a[N];
    int main()
    {
        ios_base::sync_with_stdio(0); cin.tie(0);
        int n;
        cin>>n;
        memset(a,-1,sizeof(a));
        for(int i=n-1;i>=0;i--)
        {
            int t=~i,k=0;//此时t是以补码输出的,是负数
         /***********************
            9      1001
           取反    0110  
              &    1111   
             得:   0110    
         */cout<<t;
            while(1<<k<i)k++;
            cout<<(1<<k)-1;
            t=t&((1<<k)-1);cout<<t<<endl;
            if(a[i]==-1)
                a[i]=t,a[t]=i;
        }
        for(int i=0;i<n;i++)
            cout<<a[i]<<" ";
        cout<<endl;
        return 0;
    }

     

  • 相关阅读:
    (算法)Hanoi Problem汉诺塔问题
    (剑指Offer)面试题48:不能被继承的类
    (剑指Offer)面试题47:不用加减乘除做加法
    (剑指Offer)面试题46:求1+2+3+....+n
    (剑指Offer)面试题45:圆圈中最后剩下的数字
    程序员应该知道的15件事 在生活与工作中用他们来警惕自己
    基于REST架构的Web Service设计
    互联网上五个最高级的搜索引擎
    哈佛经济学家关于工作效率的意外发现
    列举一些常见的系统系能瓶颈 Common Bottlenecks
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9452637.html
Copyright © 2011-2022 走看看