输入样例:

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

输出样例:

4

样例解释

农场的平面图如下所示,其中

H 表示约翰的房子,

B 表示牛棚:

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

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

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

题意解读:

可以理解为从原点(0,0)开始向右发射一束光,通过镜子/ \两种45°倾斜的镜子反射光,则光可以90°的角度变化到上下左右另一方向继续射出,最终需要射到终点(a,b)。

最多改变一个镜子能达到如上目标则输出改变镜子的编号,否则输出-1,不改变镜子则输出0.

思路:枚举

  • 将不翻转时和每次翻转第i个镜子的路径遍历一遍看是否走到终点,需要n+1次

  • 遍历路径方法:将镜子视为节点,从当前原点节点出发,每次当前节点都需要找到下一个镜子节点(即该镜子在当前方向上,且距离最近),方法为遍历所有的镜子节点,查看两个节点构成的向量的模乘上当前目标方向得到一个向量,再加当前节点,查看是否等于下一个节点。直到找到终点或者找不到终点。

  • 每一个路径遍历时会出现三种情况:

    • 1.如果走了(2n+1)个镜子节点了还未到终点,则一定是进入了循环到不了终点(注:2n+1是所有镜子形成循环即最大的循环需要的节点数)
  • 2.如果在当前节点找不到下一个镜子节点,则说明此方向没有镜子了,一定到不了终点

  • 3.到达终点

  • 由上可知路径遍历需要n^2时间复杂度

  • 所以枚举算法需要n^3的时间复杂度,因为n<200,故可以接受
    重点解决点:如何判断下一个点 ( x i + 1 , y i + 1 ) (x_{i+1},y_{i+1}) (xi+1​,yi+1​)在当前点的 ( x i , y i ) (x_{i},y_{i}) (xi​,yi​)目标方向 d d d{(0,1) , (1,0) ,(0,-1) , (-1,0)}上

  • 这使用向量的方法来解决进行判断,同时利用目标方向只存在于x,y轴,而不是其他方向的特点

  • 即两点形成向量的应该与方向向量平行

  • 求得两点之间的模为m,则有 ( x i , y i ) + m ∗ d = ( x i + 1 , y i + 1 ) (x_{i},y_{i}) + m*d = (x_{i+1},y_{i+1}) (xi​,yi​)+m∗d=(xi+1​,yi+1​)

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;const int N = 210;
int n;// 定义方向,上 右 下 左
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};struct Node{int x,y;char mirror;
}M[N];void change_mirror(Node &node){// 翻转镜子if(node.mirror == '\\') node.mirror = '/';else node.mirror = '\\';
}bool check(){// 遍历当前的镜子节点路径是否能到达终点int d = 1; // 方向向右int index = 0; // 当前的镜子M[0].x = M[0].y = 0; // 初始化开始位置为原点for(int i = 0;i<(2*n+1);i++){// 遍历最多(2*n+1),则一定是陷入循环了,不可能到达终点int next = -1,len = INF; // 下一个节点和下一个节点到此节点的距离for(int j = 1;j<=n+1;j++){if(index == j) continue; // 相同节点直接跳过// 当前节点 加 当前方向乘模长 需要等于 目标节点if(M[index].x + abs(M[index].x - M[j].x) * dx[d] != M[j].x) continue;if(M[index].y + abs(M[index].y - M[j].y) * dy[d] != M[j].y) continue;// 找到最近的那个节点int length = abs(M[index].x - M[j].x) + abs(M[index].y - M[j].y);if(length < len) len = length, next = j;}if(next == -1) return false; // 找不到下一个节点if(next == n+1) return true; // 找到了目标节点// 根据下一个节点的镜子更换方向index = next;if(M[next].mirror == '/'){if(d == 0) d = 1;else if(d == 1) d = 0;else if(d == 2) d = 3;else d = 2;}else{if(d == 0) d = 3;else if(d == 1) d = 2;else if(d == 2) d = 1;else d = 0;}}return false;
}int main(){/* 思路:枚举* 将每一个翻转i镜子的路径和所有都不翻转遍历一遍看是否走到终点,需要n+1次* 遍历路径方法:将镜子视为节点,从当前原点节点出发,每次当前节点都需要找到下一个镜子节点(即该镜子在当前方向上,且距离最近),方法为遍历所有的镜子节点,查看两个节点构成的向量的模乘上当前目标方向得到一个向量,再加当前节点,查看是否等于下一个节点。直到找到终点或者找不到终点。* 每一个路径遍历时会出现三种情况:*        1.如果走了(2n+1)个镜子节点了还未到终点,则一定是进入了循环到不了终点*        2.如果找不到下一个节点,则到不了终点*        3.到达终点*        由上可知路径遍历需要n^2时间复杂度* 所以枚举算法需要n^3的时间复杂度,因为n<200,故可以接受* */cin>>n;cin>>M[n+1].x>>M[n+1].y; // n+1的位置存目标for(int i = 1;i<=n;i++) cin>>M[i].x>>M[i].y>>M[i].mirror;if(check()){cout<<0<<endl;return 0;} else{for(int i = 1;i<=n;i++){change_mirror(M[i]); // 翻转镜子if(check()){cout<<i<<endl;return 0;}change_mirror(M[i]); // 改变回来}}cout<<-1<<endl;return 0;
}

ACWING/1986. 镜子相关推荐

  1. AcWing 734. 能量石 (01背包)+(贪心 - 领项交换)

    AcWing 734. 能量石 #include<cstdio> #include<algorithm> #include<cstring> #include< ...

  2. 解题报告:AcWing 352. 闇の連鎖(树上差分、方案统计)

    https://www.acwing.com/problem/content/354/ 在没有附加边的情况下,我们发现这是一颗树,那么再添加条附加边(x,y)后,会造成(x,y)之间产生一个环 如果我 ...

  3. 聪明人的游戏(3)镜子颠倒了什么?

    2019独角兽企业重金招聘Python工程师标准>>> 这是一个纯粹为了不让脑袋生锈的系列.答案都是自己写的,不保证一定正确,如有错处,欢迎指教. 想象你在镜子前,请问,为什么镜子中 ...

  4. Unity镜子效果的实现(无需镜子Shader)

    Unity镜子效果制作教程 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享 ...

  5. 40千克的镜子被量子力学“踢了一脚”,科学家首次发现宏观物体量子波动 | Nature...

    鱼羊 萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 量子力学似乎离我们的日常很远. 除了偶尔会被用来收收智商税(例如,量子波动速读). 毕竟,微观与宏观世界差异很大,前者受量子力学统治, ...

  6. 首个镜子分割网络问世,大连理工、鹏城实验室、香港城大出品 | ICCV 2019

    乾明 发自 凹非寺  量子位 报道 | 公众号 QbitAI 镜子里的人,是人吗?对于计算机视觉系统来说:是. 大部分系统也不考虑镜子因素,它们很难分清楚镜中人. 镜子作为日常生活中非常重要的物体无处 ...

  7. acwing算法题--铁路与公路

    原题链接:https://www.acwing.com/problem/content/description/4077/ #include <iostream> #include < ...

  8. acwing算法题--看图做题

    原题链接:https://www.acwing.com/problem/content/3992/ 找规律题 #include<iostream>using namespace std;i ...

  9. acwing算法题--不同的数

    原题链接:https://www.acwing.com/problem/content/3991/ #include <iostream> #include <unordered_m ...

最新文章

  1. flask url构建_如何为生产构建构建Flask-RESTPlus Web服务
  2. python最长连续子串_LeetCode 03无重复字符的最长子串(滑动窗口)
  3. CI框架源码阅读笔记4 引导文件CodeIgniter.php
  4. TensorFlow升级1.4:Cannot remove entries from nonexistent file \lib\site-pack
  5. 魔术命令python_Python前10个魔术命令可以帮助您提高生产率
  6. 谷歌开源 Python Fire:可自动生成命令行接口
  7. html网址怎么收录,新站如何快速收录 让新网站快速被收录的几点技巧
  8. 比尔盖茨正式退出微软董事会:将继续担任技术顾问
  9. suse linux vnc配置文件,怎么在linux suse中配置VNC服务器
  10. Server系列18:如何通过组策略赋予domain user受限网络管理权限?
  11. python气象绘图_Python气象绘图教程特刊(一)
  12. ABAP中分页控件的定义
  13. ARPSpoofing教程(四) - 捕获并分析数据包
  14. domain or business logic
  15. WiFi基础知识概述
  16. java异常栈_简单看java异常栈
  17. 乘法鉴相器的matlab仿真,Matlab仿真costas环代码问题。
  18. linux下创建用户分组及设置分组权限
  19. 可视化学习笔记5-pytorch利用summary()打印神经网络的结构
  20. Latex 表格内换行

热门文章

  1. SpringMVC源码分析系列[转]
  2. C语言基础:for语句
  3. Android 简单的录音静音降噪
  4. Flying.Swords.of.Dragon.Gate.2011.720p.HDTV.x264-NGB龙门飞甲
  5. 数据存储和界面展现之二
  6. vue3返回顶部组件(丝滑)
  7. ISO14064简介
  8. 省力下载网盘rapidshare、hotfile、megaupload、filesonic、f...
  9. 药一点医疗管理软件供应商—诊所管理系统
  10. java中list集合转set集合_java集合中:set与list相互转换