位运算——异或运算

2023-11-20


按位异或运算(^)

按位异或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相应位的值相同的,结果为 0,不相同的结果为 1。
例如,2 ^ 6结果为4
因为2表示为二进制为0010,6表示为二进制为0110
两数只有第三位相异,因此最后的结果为0100,即为4


了解异或运算的用法,我们来看看异或运算在算法题中的应用。

异或运算的应用

镜子田地

题目描述

农夫约翰在屋子外面放了一些旧镜子,他的奶牛们像往常一样调皮地偷走了它们!

奶牛们将镜子放置在了一个矩形田地中,该田地可被划分为 N × M N×M N×M个方格区域。

在每个方格区域中,奶牛在其某对对角之间放置一个双面镜,因此,共有两种放法,一种为/放置(镜子连接方格左下角和右上角),另一种为\放置(镜子连接方格左上角和右下角)。

一天晚上,奶牛贝茜将激光发射器带到了该田地中。

她站在田地外面,沿着田地的行或列水平或垂直照射光束,使光束反射一定数量的镜子。

由于镜子都是沿对角线摆放,因此经反射镜反射的水平光束最终将垂直传播,反之亦然。

贝茜想知道从田地之外射入的水平或垂直光束最多可以在田地中被反射多少次。

给定镜子田地的布局,请帮助贝茜计算这个数字。

输入格式

第一行包含 N N N M M M

接下来 N N N行,每行包含 M M M/\字符,表示田地中镜子的具体摆放方式。

输出格式

输出田地之外的水平或垂直光束能够被反射的最大次数。

如果可以无限反射,则输出 −1。

数据范围
1 ≤ N , M ≤ 1000 1≤N,M≤1000 1N,M1000
输入样例:

3 3
/\\
\\\
/\/

输出样例:

3

样例解释

贝茜可以从上向下沿中间列上方发射激光。

共可以反射 3 次。

题目分析

一定不会无限反射,因为这些镜子是相邻的,无限反射是需要有入口的。
我们可以枚举从每条边射入的位置进行搜索。
在这里插入图片描述
我们要清楚,任意一个数a异或同一个数两次后值依旧为a,比如7^3,结果为4,4^3后,结果仍然为7。
那么当镜子为/时,0→1、1→0、2→3、3→2。d ^= 1
当镜子为\时,0→3、3→0、1→2、2→1。d ^= 3

代码如下

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 1010;

int n, m;
char g[N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int dfs(int x, int y, int d)
{
    if (x < 0 || x > n - 1 || y < 0 || y > m - 1) return 0;

    if (g[x][y] == '/') d ^= 1;
    else d ^= 3;

    return dfs(x + dx[d], y + dy[d], d) + 1;
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++) cin >> g[i];

    int res = 0;
    for (int i = 0; i < n; i ++)
    {
        res = max(res, dfs(i, 0, 1));
        res = max(res, dfs(i, m - 1, 3));
    }

    for (int i = 0; i < m; i ++)
    {
        res = max(res, dfs(0, i, 2));
        res = max(res, dfs(n - 1, i, 0));
    }
    cout << res << endl;
    return 0;
}

镜子

题目描述

农夫约翰的奶牛在农场周围造成了太多麻烦,因此约翰希望对它们保持更密切的关注。
通过在农场的各个位置安装 N N N个反光围栏,他希望能够从 ( 0 , 0 ) (0,0) (0,0)位置的房子看到 ( a , b ) (a,b) (a,b)位置的牛棚。
在约翰农场的二维平面图中,围栏 i i i表示为以整数位置坐标 ( x i , y i ) (x_{i},y_{i}) (xi,yi)为中心的倾斜 45 45 45度(如/\)的短线段。
例如,以 ( 3 , 5 ) (3,5) (3,5)为中心,形如/的围栏可以描述为从 ( 2.9 , 4.9 ) (2.9,4.9) (2.9,4.9) ( 3.1 , 5.1 ) (3.1,5.1) (3.1,5.1)的线段。
每个围栏(以及牛棚的位置)位于不同的位置。
( 0 , 0 ) (0,0) (0,0) ( a , b ) (a,b) (a,b)处无围栏。
约翰计划坐在他的房屋 ( 0 , 0 ) (0,0) (0,0)处,并直接向右(沿 + x +x +x方向)看。
当他的目光从农场的一些反光围栏上反射出来时,他希望能够看到点 ( a , b ) (a,b) (a,b)
不幸的是,他认为其中一个反光围栏的摆放朝向不对,例如应该为/,却摆成了\
请输出给定反光围栏中,第一个能够通过改变其朝向使得约翰成功看到点 ( a , b ) (a,b) (a,b)的围栏的顺序编号。
如果约翰不需要切换任何围栏的朝向就已经可以看到点 ( a , b ) (a,b) (a,b)则输出 0 0 0
如果约翰无法通过切换单个围栏的朝向使自己看到点 ( a , b ) (a,b) (a,b)则输出 − 1 −1 1

输入格式

第一行包含三个整数 N , a , b N,a,b N,a,b
接下来 N N N行,其中第 i i i行描述第 i i i号围栏的位置和朝向。首先包含两个整数 x i , y i x_{i},y_{i} xi,yi表示其中心点位置,然后包含一个字符/\表示围栏朝向。
围栏编号从 1 1 1开始。

输出格式

输出第一个能够通过改变其朝向使得约翰成功看到点 ( a , b ) (a,b) (a,b)的围栏的顺序编号。
如果约翰不需要切换任何围栏的朝向就已经可以看到点 ( a , b ) (a,b) (a,b)则输出 0 0 0
如果约翰无法通过切换单个围栏的朝向使自己看到点 ( a , b ) (a,b) (a,b)则输出 − 1 −1 1

数据范围
1 ≤ N ≤ 200 1≤N≤200 1N200,
− 106 ≤ x i , y i , a , b ≤ 106 −106≤x_{i},y_{i},a,b≤106 106xi,yi,a,b106

输入样例:

5 6 2
3 0 /
0 2 /
1 2 /
3 2 \
1 3 \

输出样例:

4

样例解释

农场的平面图如下所示,其中 H H H表示约翰的房子, B B B表示牛棚:

3 .\.....
2 //.\..B
1 .......
0 H../...
  0123456

通过改变 ( 3 , 2 ) (3,2) (3,2)处的围栏朝向,就可以使约翰看到点 ( a , b ) (a,b) (a,b),如下所示:

3 .\.....
2 //./--B
1 ...|...
0 H--/...
  0123456
  ```

题目分析

代码如下

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 210, INF = 1e8;

int n;
struct Mirror
{
    int x, y;
    char c;
}q[N];

//坐标系跟镜子田地不一样
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

void rotate(char& c)
{
    if (c == '/') c = '\\';
    else c = '/';
}

bool check()
{
    int d = 1, k = 0;
    for (int i = 0; i < 2 * (n + 1); i ++)
    {
        int id = -1, len = INF;
        for (int j = 1; j <= n + 1; j ++)
        {
            // 遍历每个镜子需要保证当前镜子和遍历的镜子不同
            if (k == j) continue;
            // 横竖水平 欧几里得距离 看是否能够反射到
            if (q[k].x + abs(q[k].x - q[j].x) * dx[d] != q[j].x) continue;
            if (q[k].y + abs(q[k].y - q[j].y) * dy[d] != q[j].y) continue;
            int t = abs(q[k].x - q[j].x) + abs(q[k].y - q[j].y);
            //取最小的,因为不能跨镜子反射
            if (t < len) id = j, len = t;
        }
        if (id == -1) return false;
        if (id == n + 1) return true;
        k = id;
        if (q[id].c == '/') d ^= 1;
        else d ^= 3;
    }
    return false;
}

int main()
{
    cin >> n;
    cin >> q[n + 1].x >> q[n + 1].y;
    
    for (int i = 1; i <= n; i ++) cin >> q[i].x >> q[i].y >> q[i].c;
    
    if (check()) puts("0");
    else
    {
        for (int i = 1; i <= n; i ++)
        {
            rotate(q[i].c);
            if (check())
            {
                cout << i << endl;
                return 0;
            }
            rotate(q[i].c);
        }
        puts("-1");
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

位运算——异或运算 的相关文章

随机推荐

  • 计算机视觉中的深度学习6: 反向传播

    Slides 百度云 提取码 gs3n 神经网络的梯度下降 我们之前在学习线性分类器的时候 使用Loss函数以及梯度下降法来更新权重 那么对于神经网络 我们该如何计算每层神经元的权重呢 对每层W直接求导 愚蠢的方法 如上公式所示 Loss函
  • IDEA-设置VM启动参数

    点击配置 OK 使用方式 System out println System getProperty parm
  • Mysql5.7安装3306端口报错问题解决方法

    自己尝试重装Mysql 但是过程中遇到端口报错 Mysql5 7下载及安装大家可以去参考其他博客 有很详细的过程 我在安装过程中遇到了3306报错 就是在端口号的旁边会有一个感叹号 由于我是重装 我大概猜到原因是之前的Mysql没有卸载干净
  • MySQL安装之yum安装

    在CentOS7中默认安装有MariaDB 这个是MySQL的分支 但为了需要 还是要在系统中安装MySQL 而且安装完成之后可以直接覆盖掉MariaDB 1 下载并安装MySQL官方的 Yum Repository 1 root Bria
  • Linux基础之SQLite数据库

    嵌入式数据库篇 一 SQLite数据库 二 SQLite数据库安装 三 SQLite的命令用法 四 打开 创建数据库的C接口 五 C代码执行sql语句 六 C代码建表和插入数据 七 总结 一 SQLite数据库 1 简介 轻量化 易用的嵌入
  • 使用SpringSecurity

    前几天写了一个SpringBoot对拦截器的使用 在实际项目中 对一些情况需要做一些安全验证 比如在没有登录的情况下访问特定的页面应该解释的拦截处理 这一篇介绍使用SpringSecurity来做简单的安全控制 由于SpringSecuri
  • Servlet实现简单的前后端交互

    Servlet实现简单的前后端交互 首先前后端交互是啥呢 在我的理解中大概是这样的 简单的讲就是数据的交换 接下来我们来看看应该要怎么实现这个简单的交互 1 首先我们前端先不写静态页面 直接在url上将请求的参数放上去 2 后端要做的首先就
  • Mybatis+Servlet+Mysql 整合的一个小项目:对初学者非常友好,有助于初学者很快的上手Java Web

    文章目录 前言 为何要写 目录结构 1 依赖配置 1 1 创建一个web项目 1 2 依赖需求分析 1 3 pom xml 2 配置Mybatis 2 1 mybatis config xml 2 2 UserMapper xml 2 3
  • layui改变字体颜色或者背景颜色

    改变文字颜色 done function res curr count if res data length gt 0 each res data function ii dd if NOTNULL dd islatetime if par
  • 数据库开发题目-什么是视图?以及视图的使用场景有哪些?

    1 视图是一种虚表 2 视图建立在已有表的基础上 视图赖以建立的这些表称为基表 3 向视图提供数据内容的语句为 SELECT 语句 可以将视图理解为 存储起来的 SELECT 语句 4 视图向用户提供基表数据的另一种表现形式 5 视图没有存
  • 数据结构-期末复习重要知识点总结

    目录 第一章 绪论 第二章 线性表 3 顺序表表示 4 顺序表基本运算 5 链表 6 链表的基本运算 7 循环链表 8 双链表 9 静态链表 10 一元多项式表示及相加 第三章 限定性线性表 栈与队列 1 顺序栈 2 链栈 3 链队列 4
  • 三、Pytorch中tensor的内部结构

    tensor的数据结构 tensor分为头信息区 Tensor 和存储区 Storage 信息区主要保存着tensor的形状 size 步长 stride 数据类型 type 等信息 而真正的数据则保存成连续数组 由于数据动辄成千上万 因此
  • Android机顶盒网络地址端口连通性测试

    Android机顶盒网络地址端口连通性测试 文章目录 Android机顶盒网络地址端口连通性测试 1 直接telnet 2 busybox telnet 3 测试工具 一般我们使用如下三种方式进行测试 前一种不满足则执行下一种 1 外网可以
  • [POI2007]砝码Odw

    看这数据范围就不太可DP的样子 考虑贪心 首先注意到题目里有对于任意两个砝码其中一个是另一个质量整数倍的条件 所以砝码质量的种类不超过log INF 考虑按质量从小到大把砝码往容器里放 这样的话所有的砝码和容器的质量都可以除以当前砝码质量然
  • [动态系统的建模与分析]8_频率响应_详细数学推导 G(jw)_滤波器

    运放滤波器 3 反相同相比例放大电路 Multisim电路仿真 运放滤波器 2 运放反馈原理 运放滤波器 1 理想运放 虚短虚断 现代控制理论 11 现代控制理论串讲 完结 pdf获取 信号与系统在工程中 里面的一些工具应该是奠基石 电路
  • 杂七杂八的小知识

    杂七杂八的小知识 前端知识 Node js安装注意事项 Vue学习文档 Mysql数据库小知识 安装数据库后使用数据库所需步骤 MySQL远程连接 常用数据库命令 mysql数据库导入查询 StarUML使用教程 docker小知识 cma
  • 2023备战金三银四,自动化软件测试面试宝典合集(一)

    马上就又到了程序员们躁动不安 蠢蠢欲动的季节 这不 金三银四已然到了家门口 新年一过后台就有不少人问我 现在外边大厂面试都问啥 想去大厂又怕面试挂 面试应该怎么准备 测试开发前景如何 面试 一个程序员成长之路永恒绕不过的话题 每每到这个时期
  • Flutter FutureBuilder 示例

    通过示例 可以重点对FutureBuilder的各个属性的了解
  • 使用MobaXterm发布前端代码到服务器

    1 准备 先获得服务器的必须信息 如下表 序号 参数名 参数值 描述 1 服务器IP 81 71 87 37 2 登录用户名 root 3 用户私钥 如下 可保存为一个文件如pri key 一定确保格式与下面代码一样 不能有多余的空格 换行
  • 位运算——异或运算

    目录 按位异或运算 异或运算的应用 镜子田地 镜子 按位异或运算 按位异或运算将两个运算分量的对应位按位遵照以下规则进行计算 0 0 0 0 1 1 1 0 1 1 1 0 即相应位的值相同的 结果为 0 不相同的结果为 1 例如 2 6结