一、Problem

滑动解锁是智能手机一项常用的功能。你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点。这些划过的点所组成的有向折线,如果与预设的折线在图案、方向上都一致,那么手机将解锁。

所谓两个点“相邻”:当且仅当以这两个点为端点的线段上不存在尚未经过的点。

此外,许多手机都约定:这条折线还需要至少经过4个点。

为了描述方便,我们给这9个点从上到下、从左到右依次编号1-9。即如下排列:

1 2 3
4 5 6
7 8 9

那么1->2->3是非法的,因为长度不足。
1->3->2->4也是非法的,因为1->3穿过了尚未经过的点2。
2->4->1->3->6是合法的,因为1->3时点2已经被划过了。

某大神已经算出:一共有389112种不同的解锁方案。没有任何线索时,要想暴力解锁确实很难。

不过小Hi很好奇,他希望知道,当已经瞥视到一部分折线的情况下,有多少种不同的方案。

遗憾的是,小Hi看到的部分折线既不一定是连续的,也不知道方向。

例如看到1-2-3和4-5-6,
那么1->2->3->4->5->6,1->2->3->6->5->4, 3->2->1->6->5->4->8->9等都是可能的方案。

你的任务是编写程序,根据已经瞥到的零碎线段,求可能解锁方案的数目。

输入

每个测试数据第一行是一个整数N(0 <= N <= 8),代表小Hi看到的折线段数目。
以下N行每行包含两个整数 X 和 Y (1 <= X, Y <= 9),代表小 Hi 看到点 X 和点 Y 是直接相连的。

输出

对于每组数据输出合法的解锁方案数目。

输入:
8
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
程序应该输出:
2再例如:
输入:
4
2 4
2 5
8 5
8 6
程序应该输出:
258

二、Solution

方法一:dfs

列举一下要求哈:

  • 连续的线段的长度必须 >= 4
  • 如果用户看到的两个点之间有跨点,那么跨过的点必须是 vis 过的。
  • 一个点不能在一笔画操作中经过两次。

思路:

  • 用二维数组标记两个点之间存在的跨点标号 id。
  • 当枚举到存在挂点的两个点时,需要先确保跨点访问过才能继续搜索。

未知错误…

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{static class Solution {int[][] b;boolean[][] e;int[] a;boolean[] vis;int N = 10, n, res;boolean isConn(int count) {      //判断选中的点是否连通int cnt = 0;for (int i = 1; i < count; i++) {int u = a[i-1], v = a[i];if (e[u][v])cnt++;}return cnt == n;}void dfs(int x) {if (x >= 4) {if (isConn(x))res++;return;}for (int i = 1; i < N; i++) {if (vis[i])continue;if (x > 0 && !vis[b[a[x-1]][i]])continue;a[x] = i;vis[i] = true;dfs(x+1);vis[i] = false;}}void init() {Scanner sc = new Scanner(new BufferedInputStream(System.in));vis = new boolean[N];b = new int[N][N];a = new int[N];b[1][3] = b[3][1] = 2; //1和3 3和1两个点之间是2,把这总中间隔着点的两个点列举出来b[1][9] = b[9][1] = 5;b[1][7] = b[7][1] = 4;b[2][8] = b[8][2] = 5;b[3][7] = b[7][3] = 5;b[4][6] = b[6][4] = 5;b[7][9] = b[9][7] = 8;b[3][9] = b[9][3] = 6;n = sc.nextInt(); //n条边e = new boolean[N][N];while (n-- > 0) {int a = sc.nextInt(), b = sc.nextInt();e[a][b] = e[b][a] = true;}vis[0] = true;dfs(0);System.out.println(res);}}public static void main(String[] args) throws IOException {  Solution s = new Solution();s.init();}
}

原来我们不应该得到 4 个的点就 return,我们还要继续算出检查后面的点。

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{static class Solution {int[][] b;boolean[][] e;int[] a;boolean[] vis;int N = 10, res;boolean isConn(int c, int n) {int cnt = 0;for (int i = 1; i < c; i++) {int u = a[i-1], v = a[i];if (e[v][u])cnt++;}return cnt == n;}void dfs(int c, int n) {if (c >= 4) {if (isConn(c, n)) res++;}for (int i = 1; i < N; i++) {if (c > 0 && b[a[c-1]][i] > 0 && !vis[b[a[c-1]][i]])continue;if (vis[i])continue;a[c] = i;vis[i] = true;dfs(c+1,n);vis[i] = false;}}void init() {Scanner sc = new Scanner(new BufferedInputStream(System.in));vis = new boolean[N];b = new int[N][N];a = new int[N];for (int i = 1; i <= 7; i += 3) b[i][i+2] = b[i+2][i] = i+1;for (int i = 1; i <= 3; i += 1) b[i][i+6] = b[i+6][i] = i+3;b[1][9] = b[9][1] = b[3][7] = b[7][3] = 5;int T = sc.nextInt();while (T-- > 0) {int n = sc.nextInt();    //n条边e = new boolean[N][N];for (int i = 0; i < n; i++) {int a = sc.nextInt(), b = sc.nextInt();e[a][b] = e[b][a] = true;}vis[0] = true;dfs(0, n);System.out.println(res);res = 0;}}}public static void main(String[] args) throws IOException {  Solution s = new Solution();s.init();}
}

复杂度分析

  • 时间复杂度:O(...)O(...)O(...),
  • 空间复杂度:O(...)O(...)O(...),

【回溯】B042_LQ_滑动解锁(dfs + 跨点判断)相关推荐

  1. c语言中穷竭算法,hihocoder#1054 : 滑动解锁(深度优先搜索)

    描述 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上 ...

  2. C语言 · 滑动解锁

    题目:滑动解锁 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图 ...

  3. 【八中测试】滑动解锁(HihoCoder - 1054)

    B - 滑动解锁 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在 ...

  4. java实现滑动解锁

    滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上都一致 ...

  5. hihocoder#1054 : 滑动解锁(深度优先搜索)

    描述 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上 ...

  6. android搜索框功能实现_Android实现滑动解锁功能

    说到滑动解锁,就回到了2012~2014年,iPhone4S.5.5S年代,如今准备踏入2020年,这些年国产机崛起,再也不是公交车上都是iPhone4S的场景.本篇来使用ViewDragHelper ...

  7. ViewDragHelper实战,实现滑动解锁

    说到滑动解锁,就回到了2012~2014年,iPhone4S.5.5S年代,如今准备踏入2020年,这些年国产机崛起,再也不是公交车上都是iPhone4S的场景.本篇来使用ViewDragHelper ...

  8. selenium登录QQ邮箱(附带滑动解锁)

    前言 最近因为工作需要 用selenium做了一个QQ邮箱的爬虫(登录时部分帐号要滑动解锁),先简单记录一下. 这个问题先可以分为两个部分:1.登录帐号和2.滑动解锁.python版本3.5.4 问题 ...

  9. 题目:滑动解锁 蓝桥杯

    滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上都一致 ...

最新文章

  1. codeforces数学1600day6[CodeForces - 1029C多区间交+枚举,CodeForces 992C[数学公式推导],CodeForces 992B[质因数分解+暴力枚举]]
  2. 这年头,做 Python 不懂点数据结构与算法真不行!
  3. 写过Mybatis插件?那说说自定义插件是如何加载的吧?
  4. nginx负载均衡的session共享问题的解决方法
  5. 大数据成败之“监”:美团数据质量监管平台这样搭建
  6. 在图书馆学习红宝书的一天(二)· 慢慢看原型、原型链就看懂了~
  7. 为什么子线程中不能直接更新UI
  8. Go语言实现FastDFS分布式存储系统WebAPI网关
  9. JAVA调用动态链接库
  10. python常用api_[原创]IDAPython常用API整理
  11. ShardingSphere LogicSQL 的生成探索
  12. 重大改革!Python将被加入高考科目!
  13. 程序员30岁后怎么办
  14. JavaSE详细教程.1
  15. 软件项目管理 3.5.敏捷生存期模型
  16. 成功将不支持网络的USB打印机变成网络打印机
  17. 申宝投资-指数上周五中阴杀跌
  18. mysql语句统计总数_一条sql语句实现统计查询_MySQL
  19. Nova Suspend 和 Pause
  20. twitter无法获取推文_某些第三方Twitter客户端可能无法发送更长的推文

热门文章

  1. C# 之 垃圾回收机制
  2. 游走上海——城隍庙-南京路步行街-外滩-外白渡桥
  3. 408计算机组成考试大纲,2021计算机考研408大纲:计算机组成原理部分解析及备考指导...
  4. 【GaussDB精品课第3期】GaussDB(for openGauss)配套工具介绍
  5. JS时间戳、日期互相转换
  6. 量子计算 19 量子算法4 (Shor Part I)
  7. 内存与IO,磁盘IO,网络IO
  8. 戴尔win10重新安装win7系统
  9. 如何做出一个微信小程序
  10. 东南亚痴狂诈骗的背后,意外暴露一个大型“围猎”程序员的现场