欢迎大家访问我的老师的OJ———caioj.cn

题面描述

传送门

思考

Bloxorz I传送门
这道题x,yx,yx,y的范围是真的大,那就不能直接bfs了。
因为只有坚硬的地板,我们可以定一个范围,范围以外的,直接运用数学知识去算。
首先我们先预处理范围之内的。
在这里,由于x,yx,yx,y可能是负数,我们给它们:

x+=100,y+=100;

原点就变成(100,100)(100,100)(100,100),我们就拓展到200∗200200 * 200200∗200的正方形

const int nxt_x[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
const int nxt_y[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
const int nxt_lie[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}};
void pre()
{node now,nxt;queue<node>q;memset(d,-1,sizeof(d));memset(v,false,sizeof(v));now=node(100,100,0);d[100][100][0]=0;q.push(now);v[100][100][0]=true;while(!q.empty()){now=q.front();q.pop();for(int i=0;i<4;i++){nxt=now;nxt.x+=nxt_x[now.lie][i];nxt.y+=nxt_y[now.lie][i];nxt.lie=nxt_lie[now.lie][i];if(v[nxt.x][nxt.y][nxt.lie]||!pd(nxt.x,nxt.y))continue;d[nxt.x][nxt.y][nxt.lie]=d[now.x][now.y][now.lie]+1;v[nxt.x][nxt.y][nxt.lie]=1;q.push(nxt);}}
}

之后涉及到数学,我们要尽量快地到达范围内,
那么我们怎样节省步数呢?
肯定2次跳三格(自己理解一下)。
由于我们要x,yx,yx,y一次性进入范围内,而c++除法是向下取整的,我们不妨将k+2k+2k+2

int calc(int x,int y)
{int ans=0;if(!pd(x,y)){if(x>200){int k=(x-200)/3+2;ans+=k*2;x-=k*3;}if(y>200){int k=(y-200)/3+2;ans+=k*2;y-=k*3;}}return ans+d[x][y][0];
}

现将方块正放,那么
对于U⁡\operatorname{U}U,我们直接calc即可。
对于H⁡\operatorname{H}H,如图

红色为原先位置,每一个蓝色格子都为一种立着的情况,只有10种,因为对于任一第11种,可以从这10种中多走一步得到。

if(c[0]=='H')
{for(int i=-2;i<=2;i++){ans=min(ans,calc(x-i,y-1)+1+abs(i));//左边的为(x,y)ans=min(ans,calc(x-i,y+2)+1+abs(i));}
}

对于V⁡\operatorname{V}V,如图

类似H⁡\operatorname{H}H,也只有十种。

else if(c[0]=='V'){for(int i=-2;i<=2;i++){ans=min(ans,calc(x-1,y+i)+1+abs(i));ans=min(ans,calc(x+2,y+i)+1+abs(i));}
}

AC code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
using namespace std;
const int N=210;
//0 立着,1 横躺 2 竖趟
//左右上下
const int nxt_x[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
const int nxt_y[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
const int nxt_lie[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}};
int d[N][N][3];
bool v[N][N][3];char c[2];
struct node
{int x,y,lie;node(){}node(int x,int y,int lie):x(x),y(y),lie(lie){}
};
bool pd(int x,int y){return x>0&&x<=200&&y>0&&y<=200;}
void pre()
{node now,nxt;queue<node>q;memset(d,-1,sizeof(d));memset(v,false,sizeof(v));now=node(100,100,0);d[100][100][0]=0;q.push(now);v[100][100][0]=true;while(!q.empty()){now=q.front();q.pop();for(int i=0;i<4;i++){nxt=now;nxt.x+=nxt_x[now.lie][i];nxt.y+=nxt_y[now.lie][i];nxt.lie=nxt_lie[now.lie][i];if(v[nxt.x][nxt.y][nxt.lie]||!pd(nxt.x,nxt.y))continue;d[nxt.x][nxt.y][nxt.lie]=d[now.x][now.y][now.lie]+1;v[nxt.x][nxt.y][nxt.lie]=1;q.push(nxt);}}
}
int calc(int x,int y)
{int ans=0;if(!pd(x,y)){if(x>200){int k=(x-200)/3+2;ans+=k*2;x-=k*3;}if(y>200){int k=(y-200)/3+2;ans+=k*2;y-=k*3;}}return ans+d[x][y][0];
}
int main()
{pre();while(scanf("%s",c)!=EOF){int x,y;scanf("%d%d",&x,&y);int ans=2e9;x+=100,y+=100;if(c[0]=='U')ans=min(ans,calc(x,y));if(c[0]=='H'){for(int i=-2;i<=2;i++){ans=min(ans,calc(x-i,y-1)+1+abs(i));ans=min(ans,calc(x-i,y+2)+1+abs(i));}}else if(c[0]=='V'){for(int i=-2;i<=2;i++){ans=min(ans,calc(x-1,y+i)+1+abs(i));ans=min(ans,calc(x+2,y+i)+1+abs(i));}}printf("%d\n",ans);}return 0;
}

Bloxorz II[POJ3323]相关推荐

  1. POJ3323 Bloxorz II BFS

    题目链接 http://poj.org/problem?id=3323 分析 问题在于坐标范围太大,无法直接BFS. 做法是先预处理出起点周围区域到起点的最少步数,对于范围之外的情况,先尽快走进范围之 ...

  2. 剑指offer:面试题32 - II. 从上到下打印二叉树 II

    题目:从上到下打印二叉树 II 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 例如: 给定二叉树: [3,9,20,null,null,15,7], 3    / \ ...

  3. 剑指offer:面试题14- II. 剪绳子 II

    题目:剪绳子 II 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m] .请问 k[0]* ...

  4. 递归/回溯:Combination Sum II数组之和

    问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集. 例如: nums[] = [10, 1, 2, 7, 6, ...

  5. 递归/回溯:Subsets II求子集(有重复元素)

    上一篇描述了针对数组中没有重复元素进行子集的求取过程递归/回溯:subsets求子集 但是当出现如下数组时: 例如: nums[] = [2, 1, 2, 2] 结果为: [[], [1], [1,2 ...

  6. HDU 2080 夹角有多大II

    夹角有多大II Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. 了解ES6 The Dope Way Part II:Arrow功能和'this'关键字

    by Mariya Diminsky 通过玛丽亚·迪明斯基(Mariya Diminsky) 了解ES6 The Dope Way Part II:Arrow功能和'this'关键字 (Learn E ...

  8. Leetcode 213.大家劫舍II

    打家劫舍II 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两 ...

  9. 用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解 (一)

    一,概述 用Altera的话来讲,timequest timing analyzer是一个功能强大的,ASIC-style的时序分析工具.采用工业标准--SDC(synopsys design con ...

最新文章

  1. 计算器html js php代码,JavaScript计算器网页版实现代码分享
  2. maven 如何看jar是否被修改_如何在线修改jar文件
  3. 爬虫进阶教程:极验(GEETEST)验证码破解教程
  4. sudo密码一直出错
  5. python3.8.5依赖的urllib版本_Python(pip)-请求依赖警告:urllib3(1.9.1)或chardet(2.3.0)与受支持的版本不匹配...
  6. java读取csv合适文件_解析-您可以推荐一个Java库来读取(并可能写入)CSV文件吗?...
  7. 5个实用提速深度学习模型的方法
  8. VisualStudio移动开发(C#、VB.NET)Smobiler开发平台——BarcodeView控件的使用方式,.Net移动开发...
  9. 8.8 Sencha Studio 监视工具( Inspect Tool)
  10. Noip 2016 Day1 题解
  11. Ceph Monitor基础架构与模块详解
  12. paip.软件及网站项目开发效率低下的思索与改进
  13. STM32 PWM呼吸灯程序
  14. 【线上课程】4节课8小时培训,《白话区块链》作者蒋勇教你快速掌握区块链智能合约开发...
  15. Unicode编码之显示定向重写
  16. HBuilderX前端html功能拓展应用
  17. 用rtl8139网卡制作的bios编程器(不用并口)
  18. 编写Linux下的USB键盘驱动(附源码)
  19. 1分钟理清楚C++类模板和模板类区别
  20. 低代码平台要怎么选?便宜其实也有好货!

热门文章

  1. linux虚拟机挂载USB3.1U盘报错
  2. 微信小程序,配置web-view业务域名,文件检测失败
  3. 计算机辅助设计和辅助教学,计算机辅助设计教学存在的问题与改革
  4. 推出 5 年后,微软想用设计「全面复兴」Windows 10
  5. mysql5.7 flashback_Flashback for MySQL 5.7
  6. 编程英语:npm 全称
  7. 激光镜像 傻瓜方法 c++
  8. #linux# gcc编译器优化选项的详细信息
  9. Rust入坑指南:亡羊补牢
  10. python 调用企查查接口平台