题目描述

小明冒充X星球的骑士,进入了一个奇怪的城堡。城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。
按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)
同一个方格只允许经过一次。但不必走完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入
第一行一个整数N(0<N<20),表示地面有 N x N 个方格
第二行N个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行N个整数,空格分开,表示西边的箭靶上的数字(自北向南)
输出
一行若干个整数,表示骑士路径
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3…
比如,上图中的方块编号为:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
样例输入
4
2 4 3 4
4 3 3 3
样例输出
0 4 5 1 2 3 7 11 10 9 13 14 15

代码如下:

#include <iostream>
#include <cstring>
using namespace std;
int dx[] = {0,0,1,-1},dy[] = {1,-1,0,0};//方向向量
const int N = 21;
int mp[N][N];//存储地图编号
bool st[N][N];//标记地图某格是否走过或者能不能走
int path[410];//存储路径,这个数组要开大一点,它搜索的时候可能有一次搜索会把全部格子都走了
int n;
int flagx[N],flagy[N];//每走一格射的靶子,用来判断与题目输入的靶子是否相同
int tarx[N],tary[N];//题目输入的靶子数目
int flagxs,flagys;
void PrintPath(int index)//输出结果函数,也可以加入dfs中,就是加进去的话代码比较丑
{for (int i = 1;i<=index;i++){cout<<path[i]<<" ";}cout<<endl;
}void dfs(int x,int y,int index)//搜索路径
{if (x==n && y==n)//判断是否到达终点{for (int i = 1;i<=n;i++){if (flagx[i]==tarx[i]) flagxs++;if (flagy[i]==tary[i]) flagys++;}if (flagxs==n && flagys==n)//判断到达终点后靶子数目是否相同{PrintPath(index);return ;}else{flagxs = 0;flagys = 0;return;}}for (int i = 0;i<4;i++){int xx = x+dx[i],yy = y+dy[i];if (st[xx][yy]) continue;flagx[xx]++;flagy[yy]++;path[index+1] = mp[xx][yy];st[xx][yy] = true;dfs(xx,yy,index+1);st[xx][yy] = false;flagx[xx]--;flagy[yy]--;}
}int main()
{cin>>n;for (int i = 1;i<=n;i++) cin>>tary[i];for (int i = 1;i<=n;i++) cin>>tarx[i];memset(st,1,sizeof(st));int k = 0;for (int i = 1;i<=n;i++)for (int j = 1;j<=n;j++){mp[i][j] = k++;st[i][j] = false;}st[1][1] = true;//标记起点flagx[1] = 1;flagy[1] = 1;path[1] = 0;dfs(1,1,1);return 0;
}

可惜这样暴搜超时了,无法AC,我们要想办法剪枝。

剪枝优化AC代码如下:

#include <iostream>
#include <cstring>
using namespace std;int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
const int N = 21;
int mp[N][N];
bool st[N][N];
int tarx[N], tary[N];
int n;
int sum;//这条路线的总步数
int path[410];void PrintPath(int index) {for (int i = 1; i <= index; i++) {cout << path[i] << " ";}cout << endl;
}void dfs(int x, int y, int index) {if (index > sum)//当它搜索的时候超过总步数(多走了),就说明肯定不是走这条路,所以重新选路return;for (int i = 1; i <= n; i++) {if (tarx[i] < 0 || tary[i] < 0)//当有靶子减没了,也肯定是走错路了return;}if (x == n && y == n && sum == index) {//只有刚好到终点,且走的步数与总步数相等,就说明是这条路了PrintPath(index);return ;}for (int i = 0; i < 4; i++) {int xx = x + dx[i], yy = y + dy[i];if (st[xx][yy])continue;tary[yy]--;tarx[xx]--;st[xx][yy] = true;//记得标记path[index + 1] = mp[xx][yy];dfs(xx, yy, index + 1);st[xx][yy] = false;//要记得"还原现场"tary[yy]++;tarx[xx]++;}}int main() {cin >> n;for (int i = 1; i <= n; i++) {cin >> tary[i];sum += tary[i];}for (int i = 1; i <= n; i++)cin >> tarx[i];memset(st, 1, sizeof(st));int k = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++) {mp[i][j] = k++;st[i][j] = false;}st[1][1] = true;tary[1]--;//注意,刚开始要把(1,1)位置的靶子先减掉tarx[1]--;path[1] = 0;dfs(1, 1, 1);return 0;
}

[蓝桥杯2016决赛]路径之谜相关推荐

  1. 蓝桥杯题目练习 提升篇 [蓝桥杯2016决赛]路径之谜

    路径之谜 题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡.城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格. 按习俗,骑士要从西北角走到东南角.可以横向或纵向移动 ...

  2. 蓝桥杯真题 路径之谜【第七届】【决赛】【C组】(C语言实现)

    小明冒充X星球的骑士,进入了一个奇怪的城堡. 城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.如下图所示: 按习俗,骑士要从西北角走到东南角. 可以横向或纵向移动,但 ...

  3. [蓝桥杯2016决赛]愤怒小鸟-模拟

    题目描述 X星球愤怒的小鸟喜欢撞火车! 一根平直的铁轨上两火车间相距 1000 米.两火车 (不妨称A和B) 以时速 10米/秒 相对行驶. 愤怒的小鸟从A车出发,时速50米/秒,撞向B车,然后返回去 ...

  4. [蓝桥杯2016决赛]七星填数-next_permutation枚举

    题目描述 如下图所示: 在七角星的14个节点上填入1~14 的数字,不重复,不遗漏.要求每条直线上的四个数字之和必须相等. 图中已经给出了3个数字.请计算其它位置要填充的数字,答案唯一. 填好后,请提 ...

  5. [蓝桥杯2016决赛]阶乘位数-数论

    题目描述 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计算,9999 的阶乘的二进制表示一共有多少位? 输出 输出一个整数表示答案 ...

  6. [蓝桥杯2016决赛]平方末尾-数论,枚举

    题目描述 能够表示为某个整数的平方的数字称为"平方数".比如,25,64 虽然无法立即说出某个数是平方数,但经常可以断定某个数不是平方数. 因为平方数的末位只可能是:[0, 1, ...

  7. [蓝桥杯2016决赛]反幻方-next_permutation枚举

    题目描述 我国古籍很早就记载着 2 9 4 7 5 3 6 1 8 这是一个三阶幻方.每行每列以及对角线上的数字相加都相等. 下面考虑一个相反的问题. 可不可以用 1~9 的数字填入九宫格,使得:每行 ...

  8. [蓝桥杯2016决赛]一步之遥-枚举

    题目描述 从昏迷中醒来,小明发现自己被关在X星球的废矿车里.矿车停在平直的废弃的轨道上. 他的面前是两个按钮,分别写着"F"和"B". 小明突然记起来,这两个按 ...

  9. 蓝桥杯javaB决赛历届真题6-10届

    蓝桥杯javaB决赛历届真题 第六届 T1 分机号 T2 五星填数 T3 显示二叉树 T4 穿越雷区 T5 表格计算 T6 铺瓷砖 第七届 T1 愤怒小鸟 T2 反幻方 T3 打靶 T4 路径之谜 T ...

最新文章

  1. linux Makefile 中使用 shell命令
  2. DevExpress WinFormsSuite 本地化(Simplified Chinese OR Traditional Chinese)
  3. OpenGL 帧缓冲Framebuffers
  4. java主界面设置背景图片_java 窗体设置背景图片问题?(附上登陆界面代码,我想加个背景图片,求大神帮忙改改)...
  5. 浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
  6. P2567 [SCOI2010]幸运数字
  7. HTML特殊符号/特殊字符
  8. 想要AI优先?数据优先才行
  9. 【软件测试】测试需求分析
  10. uglifyjs报错 webpack_vue使用uglifyjs-webpack-plugin后打包报错
  11. html为什么要进行表单验证_为什么要进行新旧房屋加固改造?
  12. matlab学期大作业,matlab期末大作业
  13. 郭德纲 相声下载(续)
  14. 义隆单片机可用c语言写了吗,义隆单片机编程时应注意的几点
  15. origin画图记录
  16. ElementUI上传文件和额外参数
  17. net npf 服务名无效_win10系统打开wireshark提示npF驱动没有运行的处理方法
  18. 深入剖析ISA防火墙策略执行过程
  19. 微信小程序自定义导航栏,实现自适应
  20. 真人真事,来自一位架构师的呐喊:杜绝面向监狱编程,程序员做好自身防护,时刻保持敬畏之心

热门文章

  1. Fiddler之解决https链接返回数据显示乱码问题
  2. C和指针之数组编程练习5 (矩阵相乘)
  3. 汇编语言之转移指令和原理
  4. Android之mediarecorder中的方法以及工作流程的过程
  5. c语言在win8系统不兼容,Win8系统中存在不兼容软件如何解决?
  6. 06-广度优先搜索:图、队列
  7. 世界上最奇异的10种树,你都见过吗?
  8. 令人惋惜的天才新秀:16岁上剑桥大学,27岁就出名,数学事业一路畅通无阻,但自从结婚后,人生从此翻天覆地······
  9. 按照演算,整个宇宙将会陷入无边的黑暗
  10. http服务器异步响应,python – 具有异步响应的Twisted http服务器,其中请求必须等待数据变为可用或超时...