<<操作,&0xff以及|的巧妙运用(以POJ3523---The Morning after Halloween(UVa 1601)为例)
<<表示左移,如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)为例)的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- Uva LV 2995 Image Is Everything 模拟,坐标映射,视图映射 难度: 1
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- Jenkins详细安装与构建部署使用教程
版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 目录(?)[+] Jenkins是一个开源软件项目,旨在提供一个开 ...
- vue-router-5-命名路由
创建 Router 实例的时候,在 routes 配置中给某个路由设置名称 const router = new VueRouter({ routes: [ { path: '/user/:userI ...
- python 定义class时的内置方法
__contains__():对类实例使用in ,not in操作时调用 class A(object): def __init__(self,num): self.num=num def __con ...
- node fs 解决回调地域问题
promisify问题 promisify = require('util).promisify const read = promisify( fs.readFile); read('input.t ...
- Docker小白从零入门到实战系列【二】
1.安装好Centos 7 2.关闭SELINUX sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/configsetenfo ...
- 1.3用socketserver创建服务器
socket服务器代码 # -*- coding: utf-8 -*-import socketserver,time myHost = '' myPort = 50007 def now(): #返 ...
- jackson中的@JsonBackReference
# StackOverflowError / 无限递归 / json递归 / JsonBackReference 环境:springmvc+hibernate+json 在controller返 ...
- MATLAB 地图工具箱 m_map 的安装和入门技巧(转)
reference: http://blog.sina.com.cn/s/blog_8fc890a20102v6pm.html 需要用一些地图工具,arcgis懒得装了,GMT(generic m ...
- [HAOI2006]l旅行
这道题...一眼看出一个暴力思虑...那就是按照生成树... 排完序之后从当前边开始向后做生成树... 统计一下答案就好了... 结果...这就是正解...QVQ...smg...我去... 呆码: ...