• hiho_1054_滑动解锁


    题目大意

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

    题目分析

        首先,尝试求解没有给定线段情况下,所有合法的路径的总数。可以使用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
    ", total_count);
    	}	
    	return 0;
    }
    
  • 相关阅读:
    一步一步学EF系列【4、升级篇 实体与数据库的映射】live writer真坑,第4次补发
    一步一步学EF系列3【升级篇 实体与数据库的映射】
    一步一步学EF系列2【最简单的一个实例】
    一步一步学EF系列1【Fluent API的方式来处理实体与数据表之间的映射关系】
    MVC5 Entity Framework学习之创建复杂的数据模型
    Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
    动手写一个Remoting接口测试工具(附源码下载)
    通信服务器群集——跨服务器通信Demo(源码)
    轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)
    PAT A1011 World Cup Betting(20)
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/5538099.html
Copyright © 2020-2023  润新知