题目大意

智能手机九点屏幕滑动解锁,如果给出某些连接线段,求出经过所有给出线段的合法的滑动解锁手势的总数。题目链接: 
滑动解锁

题目分析

首先,尝试求解没有给定线段情况下,所有合法的路径的总数。可以使用dfs进行搜索。代码如下:

void dfs(int row, int col, int cur_len) {
visited[row][col] = true;
if (cur_len >= 4) { //到达该点时,走过的路径长度大于等于4,则为合法的一个解锁手势
total_count++;
}
if (cur_len == 10)
return;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int next_row = (row + i) % 3;
int next_col = (col + j) % 3;
if (!visited[next_row][next_col]) {
//可能出现当前点和下一个点的连线上经过了另一个点的情况,进行判断。如果
//经过的另一个点之前被访问过,则这次仍然是合法的。
if (abs(row - next_row) == 2 && abs(col - next_col) != 1 ||
abs(col - next_col) == 2 && abs(row - next_row) != 1) {
int mid_row = (row + next_row) / 2;
int mid_col = (col + next_col) / 2;
if (!visited[mid_row][mid_col]) {
continue;
}
}
int cur = 3 * row + col;
int next = 3 * next_row + next_col;
dfs(next_row, next_col, cur_len + 1, need_use, cur_used + 1);
}
}
}
visited[row][col] = false;
}

在上面的dfs搜索基础上,添加对已有线段的限制。9个点,维护 connected[9][9], connected[i][j] 表示已经有线段将i和j连接。搜索的时候,还需要维护状态,cur_used表示当前已经经过了已有线段的数目,如果已经经过了所有的线段。且当前路径经过点数大于等于4,则是一个合法的解锁路径。

实现

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
bool visited[3][3];
bool connected[9][9];
int total_count;
//cur_len 为到达row,col点时候,路径的长度; cur_used表示已经走过的路径所覆盖的已有线段的个数
void dfs(int row, int col, int cur_len, int need_use, int cur_used) {
visited[row][col] = true;
if (cur_len >= 4 && need_use == cur_used) {
total_count++;
}
if (cur_len == 10)
return;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int next_row = (row + i) % 3;
int next_col = (col + j) % 3;
if (!visited[next_row][next_col]) {
if (abs(row - next_row) == 2 && abs(col - next_col) != 1 ||
abs(col - next_col) == 2 && abs(row - next_row) != 1) {
int mid_row = (row + next_row) / 2;
int mid_col = (col + next_col) / 2;
if (!visited[mid_row][mid_col]) {
continue;
}
}
int cur = 3 * row + col;
int next = 3 * next_row + next_col;
if(connected[cur][next])
dfs(next_row, next_col, cur_len + 1, need_use, cur_used + 1);
else
dfs(next_row, next_col, cur_len + 1, need_use, cur_used);
}
}
}
visited[row][col] = false;
}
void GetCount(int need_use) {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
dfs(row, col, 1, need_use, 0);
}
}
}
int main() {
memset(visited, false, sizeof(visited));
int T, need_use, u, v;
scanf("%d", &T);
while (T--) {
total_count = 0;
memset(connected, false, sizeof(connected));
scanf("%d", &need_use);
for (int i = 0; i < need_use; i++) {
scanf("%d %d", &u, &v);
connected[u-1][v-1] = connected[v-1][u-1] = true;
}
GetCount(need_use);
printf("%d\n", total_count);
}
return 0;
}

hiho_1054_滑动解锁的更多相关文章

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

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

  2. Swift: 打造滑动解锁文字动画

    原文:Swift: 打造滑动解锁文字动画 最近木事,找出来玩了玩facebook的paper.到处都是那个"slide to unlock your phone"的效果啊.忽闪忽闪 ...

  3. Selenium模拟JQuery滑动解锁

    滑动解锁一直做UI自动化的难点之一,我补一篇滑动解锁的例子,希望能给初做Web UI自动化测试的同学一些思路. 首先先看个例子. https://www.helloweba.com/demo/2017 ...

  4. hihocoder 1054 滑动解锁 dfs

    详细分析见滑动解锁分析 AC代码 #include <cstdio> #include <cmath> #include <cctype> #include < ...

  5. C语言 · 滑动解锁

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

  6. jq实现简单的滑动解锁效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. APP九宫格滑动解锁的处理

    写手机自动化测试脚本关于APP九宫格滑动解锁方面采用了appium API 之 TouchAction 操作. 先是用uiautomatorviewer.bat查询APP元素坐标: 手工计算九宫格每个 ...

  8. 【转】Selenium模拟JQuery滑动解锁

    滑动解锁一直做UI自动化的难点之一,我补一篇滑动解锁的例子,希望能给初做Web UI自动化测试的同学一些思路. 首先先看个例子. https://www.helloweba.com/demo/2017 ...

  9. css3做ipone当时的滑动解锁闪亮条

    现在一般的登录 注册 什么  的页面,都是会做个滑动验证.一般都是像IPONE早期那个 滑动开屏的效果 ,这个效果现在可以用CSS3来实现. 主要用到几个属性 background 背景使用渐变属性, ...

随机推荐

  1. 基于clahe的图像去雾

    基于clahe的图像去雾     通过阅读一些资料,我了解到clahe算法对图像去雾有所价值,正好opencv中有了实现,拿过来看一看.   但是现在实现的效果还是有所差异 #);    clahe] ...

  2. Unity-Animato深入系列---FloatValue阻尼

    回到 Animator深入系列总目录 Animator的SetFloat接口可以设置阻尼,并且4种类型变量只有float是支持阻尼的. public void SetFloat(int id, flo ...

  3. python学习笔记-day4笔记 常用内置函数与装饰器

    1.常用的python函数 abs             求绝对值 all               判断迭代器中所有的数据是否为真或者可迭代数据为空,返回真,否则返回假 any          ...

  4. Oracle之ORA-00972: identifier is too long

    一.前言 今天在程序的日志中出现这个错误,网上搜了一下发现,说是Oracle的对象名字最多是30个字符,不能超过30,而我出错的sql是: "select * from test where ...

  5. centOS6.5安装SUN-jdk7

    一.下载SUN-JDK1.7.tar.gz文件他 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1 ...

  6. 区分一下dpkg,rpm和yum以及apt-get

    一般来说著名的 Linux 系统基本上分两大类: RedHat 系列:Redhat.Centos.Fedora 等 Debian 系列:Debian.Ubuntu 等 Dpkg (Debian系):U ...

  7. Struts2的输入校验(1)——校验规则文件的编写

    Struts2的输入校验(1) --校验规则文件的编写 Struts2提供了基于验证框架的输入校验,所有的输入校验只要编写配置文件,Struts2的验证框架将会负责进行服务器校验和客户端校验. 注: ...

  8. DirectX 矩阵

    基础: 下标:第一个下标为该元素所在行的索引,第二个下标为该元素所在列的索引.如下图所示 行向量和列向量:只有单行的向量称为行向量,只有单列的称之为列向量. 相等 维数和元素都相等 数乘(与标量相乘) ...

  9. ubuntu下chromium 安装flash player

    原文地址 :http://blog.sina.com.cn/s/blog_858820890102v63w.html 不记得从什么时候起,Chromium 不再支持 Netscape plugin A ...

  10. linux下vim命令详解

    高级一些的编辑器,都会包含宏功能,vim当然不能缺少了,在vim中使用宏是非常方便的::qx     开始记录宏,并将结果存入寄存器xq     退出记录模式@x     播放记录在x寄存器中的宏命令 ...