位运算

[题解]UVA1603 破坏正方形 Square Destroyer

孤街醉人 提交于 2019-11-26 10:10:24
是一道启发式搜索和位运算,剪枝的杂合题目。 要学好搜索,搜索是很重要的算法。那些很厉害的选手都是搜索打得好的。(By Instructor Li) 题目分析 首先, \(N≤5\) ,且边数是 \(2N(N+1)≤60\) 。在这样的小数据下可以位运算优化。 启发式搜索,设计估价函数 \(G(X)\) 。要求低于真实代价。下面是一种方法: 对于每一个正方形,删除它的所有边。重复这个操作知道没有正方形。操作的次数就是估价 然而,仅仅这样不足以过掉这题。还需要优化。 判断正方形 在纸上推导一下,或者直接找规律,可以得到: 如果一条横放的火柴编号为 \(X_0\) , \(X_0\) 左下方的 \(L\) 根火柴分别是:$ X_i=X + (2i-1) N + i - 1,(0<i<L)$。 那么正方形的左边界确定了,右边界的编号就是左边界加上边长。 预处理出所有的正方形,并且按照从小到大的顺序。原因后面会说 这样在DFS函数里减少了判断正方形的开销 位运算的技巧 用==unsigned long long==存储一个正方形的边的编号。 利用==&==,==|==运算符可以完成判断正方形是否存在,在一个状态上增加边等操作。具体实现方法是 #define Mark(X,K) (X=X|((Ull)1<<((K)-1))) #define Del(X,K) (X&(~((Ull)1<<((K

NumPy 位运算

試著忘記壹切 提交于 2019-11-26 08:28:45
章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基于数值区间创建数组 NumPy 数组切片 NumPy 广播 NumPy 数组迭代 NumPy 位运算 NumPy 字符串函数 NumPy 数学函数 NumPy 统计函数 NumPy 排序、查找、计数 NumPy 副本和视图 NumPy 矩阵库函数 NumPy 线性代数 NumPy 位运算 NumPy包中,可用位操作函数进行位运算。 bitwise_and 位与运算 bitwise_or 位或运算 invert 位非运算 left_shift 左移位 right_shift 右移位 bitwise_and 要对数值进行位与运算,可以使用 bitwise_and() 函数。 示例 import numpy as np print ( '\n13与17的二进制表示:' ) a , b = 13 , 17 print ( bin ( a ) ) print ( bin ( b ) ) print ( '\n13与17相与:' ) c = np . bitwise_and ( 13 , 17 ) print ( bin ( c ) ) 输出 13与17的二进制表示: 0b1101 0b10001 13与17相与: 0b1

位运算和取模运算的运算效率对比

旧时模样 提交于 2019-11-26 06:36:11
前言   总说计算机是擅长于做位运算的,那么到底它有多擅长呢?   通过简单的测试,来探究一样位运算和取模运算的运算效率对比。 一、测试代码: 1 public class BitAndModulus { 2 @Test 3 public void bit() { 4 int number = 10000 * 10;//分别取值了10万、100万、1000万、1亿 5 int a = 1; 6 7 long start = System.currentTimeMillis(); 8 for(int i = number; i > 0 ; i++) { 9 a &= i; 10 } 11 long end = System.currentTimeMillis(); 12 System.out.println("位运算耗时: " + (end - start)); 13 } 14 15 @Test 16 public void modulus() { 17 int number = 10000 * 1000;//分别取值了10万、100万、1000万、1亿 18 int a = 1; 19 20 long start = System.currentTimeMillis(); 21 for(int i = number; i > 0; i++) { 22 a %= i; 23 } 24

位运算

空扰寡人 提交于 2019-11-26 02:49:12
题引 ** 题引是不存在的 ** 1.关于原码与补码 原码:由十进制数转化为二进制数,如10:00001010( 偷懒就8位 ),-25:00011001. 补码:正数的补码就是原码,负数的补码为其原码按位取反后加一(符号位不变) 位运算是由补码进行计算!! 例子(负数) -25 原码:00011001 过程: 00011001->11100110->11100111(补码) 2.左移(<<)和右移(>>) 左移:符号位不变,右边补0(数量由具体例子决定) 右移:符号位不变,右边去除部分为(数量有具体例子决定)(如果符号位为0,左边补0;符号位为1,左边补1) 例子 1.正数的左移(10) 10<<3:00001010(补码)->01010 000 (80) 2.正数的右移(10) 10>>3:00001010(补码)-> 000 00001 010 (1) 3.负数的左移(-25) -25<<3:11100111(补码)-> 1 00111 000 (符号位不变)->100111011(减1)->011000100(取反)(-196) 4.负数的右移(-25) -25>>3:11100111-> 111 11100 111 *->11111011->0000100(-4) 3.与(&),或(|),异或(^) 三者都为补码运算 &:同为1才为1 | :同为0才为0 ^:相同为0