<<表示左移,如a<<1表示将a的二进制左移一位,加一个0,&0xff表示取最后8个字节,如a&0xff表示取a表示的二进制中最后8个数字组成一个新的二进制数,| 运算符表示对2个数的二进制位进行比较,只要2个之中有一个这个位是1,则2者进行或运算之后得到的那个二进制数相应的位也是1。

因此,可以将3个数进行左移操作,然后再进行或运算,最后得到一个数,然后就可以通过这个数进行右移操作再进行&0xff操作就能得到原来的数。由于直接对二进制进行操作,因而速度极快。

有读者可能会说可以直接开一个结构体,将3个数都归属于一个结构体中,这样当然可以,不过速度远慢于上述操作。

对于POJ3523---The Morning after Halloween(UVa 1601)题目,运用结构体的运行时间是4672MS,而用第一个方法的运行时间是3719MS。所以明显第一个方法远远优于结构体方法。

以下为题目完整代码:

///本题可以通过对空白格进行构图,从而减少广搜时所需的操作时间。可以对每个空格进行编号,然后记录开始状态和结束状态,从开始状态对图进行广搜

#include<cstdio>
#include<queue>
#include<cstring>
#include<cctype>
using namespace std; const int maxs=;
const int maxn=;
const int dr[]= {,-,,,}; /// 4 moves, plus "no move"
const int dc[]= {,,,-,}; inline int ID(int a, int b, int c)
{
return (a<<)|(b<<)|c;///由于int 类型保存8个字节,所以这个操作将a放到了最前面的8个字节,b放到了中间的8个字节,c放到了最后的8个字节
} int s[],t[];///s表示开始位置,t表示终点位置
int degree[maxn],G[maxn][];
inline bool conflict(int a, int b, int a2, int b2)
{
return a2 == b2 || (a2 == b && b2 == a);///第一个表示a,b进入同一空格,第二个表示2者交换位置
}
int d[maxn][maxn][maxn];///表示所走的总步数 int bfs()
{
queue<int> q;
q.push(ID(s[],s[],s[]));
memset(d,-,sizeof(d));
d[s[]][s[]][s[]]=;
while(!q.empty())
{
int u=q.front();
q.pop();
int a=(u>>)&0xff,b=(u>>)&0xff,c=u&0xff;
if(a==t[]&&b==t[]&&c==t[]) return d[a][b][c];
for(int i=;i<degree[a];i++)///从第一个鬼开始,查找连通的空格
{
int a2=G[a][i];
for(int j=;j<degree[b];j++)
{
int b2=G[b][j];
if(conflict(a,b,a2,b2)) continue;
for(int k=;k<degree[c];k++)
{
int c2=G[c][k];
if(conflict(a, c, a2, c2)) continue;
if(conflict(b, c, b2, c2)) continue;
if(d[a2][b2][c2]!=-) continue;///判断是否被访问过
d[a2][b2][c2]=d[a][b][c]+;
q.push(ID(a2,b2,c2));
}
}
}
}
return -;
} int main()
{
int w,h,n;
while(~scanf("%d%d%d\n",&w,&h,&n)&&w)
{
char maze[][];
for(int i = ; i < h; i++)
fgets(maze[i], , stdin); int cnt,x[maxn],y[maxn],id[maxs][maxs];///cnt 用于计数,id数组用于记录空格所处位置及其编号
cnt=;
for(int i=; i<h; i++)
for(int j=; j<w; j++)
if(maze[i][j]!='#')
{
x[cnt]=i;
y[cnt]=j;
id[i][j]=cnt;
if(islower(maze[i][j])) s[maze[i][j]-'a']=cnt;
else if(isupper(maze[i][j])) t[maze[i][j]-'A']=cnt;
cnt++;
} for(int i=; i<cnt; i++) ///建图
{
degree[i]=;
for(int dir=; dir<; dir++)
{
int nx=x[i]+dr[dir];
int ny=y[i]+dc[dir];
if(maze[nx][ny]!='#') G[i][degree[i]++]=id[nx][ny];
}
}
///加入假鬼,使3种情况都能按照3个鬼的bfs进行,由于假鬼开始就待在终点,所以不会对结果产生影响
if(n <= )
{
degree[cnt] = ;
G[cnt][] = cnt;
s[] = t[] = cnt++;
}
if(n <= )
{
degree[cnt] = ;
G[cnt][] = cnt;
s[] = t[] = cnt++;
}
printf("%d\n",bfs());
}
return ;
}

<<操作,&0xff以及|的巧妙运用(以POJ3523---The Morning after Halloween(UVa 1601)为例)的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. localStorage 设置本地缓存

    var timestamp = parseInt(Date.parse(new Date()));var btn = document.getElementById("close" ...

  2. nginx test

    nginx   1◆   /etc/init.d/httpd start     yum install httpd -y   192.168.163.104   lsof -i :80     yu ...

  3. composer install Your requirements could not be resolved to an installable set of packages

    composer install --ignore-platform-reqs 或者 composer update --ignore-platform-reqs

  4. laravel获取当前的url以及当前的基础域名方法汇总

    原文地址:https://phpartisan.cn/news/58.html 来源于:laravel获取当前的url以及当前的基础域名方法汇总 - Laravel学习网 laravel中我们常常需要 ...

  5. linux网络操作 配置文件

    网络接口配置文件(网卡信息文件) '/etc/sysconfig/network-srcipts/ifcfg-*(eth0)' (注意区分大小写) DEVICE=eth0 网卡编号 HWADDR=08 ...

  6. JAVA⑤

    1.定义一个常量 * * 01.一旦被赋予初始值 不允许被改变 * 02.常量名全大写 * 03.如果有多个单词,每个单词使用_ 分割 2. == : * 01. 数值类型 使用的时候 比较的是 值 ...

  7. OO作业总结报告3

    规格化设计的发展史 下面部分来源:https://www.cnblogs.com/eggert/p/9098446.html: 随着计算机硬件的飞速发展,以及应用复杂度越来越高,软件规模越来越大,原有 ...

  8. CentOS7安装配置Bacula yum方法

    参考: https://www.baidu.com/link?url=o2QIy2YZWjsJPAFJuYFhrH3nPvtyRkSe-o5Q_FqFZ5E1EMOsIOmGeKm0HAonwHOw8 ...

  9. java中Calendar类

    1.测试代码: package com; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util. ...

  10. 杭电多校第七场 1010 Sequence(除法分块+矩阵快速幂)

    Sequence Problem Description Let us define a sequence as below f1=A f2=B fn=C*fn-2+D*fn-1+[p/n] Your ...