📜  制作手机锁图案的方法数量

📅  最后修改于: 2021-04-24 18:12:00             🧑  作者: Mango

手机图案是3X3单元的网格,在其中绘制特定的图案(按顺序连接特定的单元序列)将解锁手机。在此问题中,任务是计算在给定范围内具有连接数量的锁定方式的数量。一般而言,我们给定的范围是最小和最大,我们需要告诉我们可以使用至少最小连接单元格和最多最大连接单元格来制作多少个模式。

输入:最小= 5,最大= 7输出:106080下面是一些示例模式模式1

一个简单的解决方案是通过从所有起点进行各种连接来进行简单的DFS。我们可以通过查看模式之间的对称性来进行优化,将单元格1、3、7和9视为相同。同样,我们可以将2、4、6和8视为相同。同一组成员返回的答案可以乘以4,以得到所有成员的结果。
接下来要注意的是,以下模式无效,因为不允许跳转某些单元格,如下面的图所示,单元格8和单元格5、6都被跳转了。
模式2

为了处理此类无效动作,在下面的代码中采用了2D跳转数组,该数组将可能的跳转单元存储在跳转数组中。当我们递归调用时,我们施加了一个额外的条件,即如果我们正从一个包含某个跳跃单元的单元移动到另一个单元,则应该已经访问了该单元以忽略无效移动。
在下面的代码中,我们仅从1、2和5进行了递归调用,因为由于对称,1将覆盖3、5和7,而2将覆盖4、6和8。
请参阅以下代码,以更好地理解:

C++
//  C/C++ program to find number of ways to lock the mobile
// pattern
#include 
using namespace std;
#define DOTS 10
  
//  method to find total pattern starting from current cell
int totalPatternFromCur(bool visit[DOTS], int jump[DOTS][DOTS],
                                          int cur, int toTouch)
{
    if (toTouch <= 0)
    {
        //  if last cell then return 1 way
        return (toTouch == 0)? 1 : 0;
    }
  
    int ways = 0;
  
    //  make this cell visited before going to next call
    visit[cur] = true;
  
    for (int i=1; i


Java
// Java program to find number of ways 
// to lock the mobile pattern
class GFG 
{
static int DOTS = 10;
  
// method to find total pattern starting from current cell
static int totalPatternFromCur(boolean visit[], int jump[][],
                                       int cur, int toTouch)
{
    if (toTouch <= 0)
    {
        // if last cell then return 1 way
        return (toTouch == 0) ? 1 : 0;
    }
  
    int ways = 0;
  
    // make this cell visited before 
    // going to next call
    visit[cur] = true;
  
    for (int i = 1; i < DOTS; i++)
    {
          
    /* if this cell is not visit AND
        either i and cur are adjacent (then jump[i][cur] = 0)
        or between cell must be visit already (
        then visit[jump[i][cur]] = 1) */
    if (!visit[i] && (jump[i][cur] == 0 || 
         visit[jump[i][cur]]))
        ways += totalPatternFromCur(visit, jump, 
                                    i, toTouch - 1);
    }
  
    // make this cell not visited
    // after returning from call
    visit[cur] = false;
  
    return ways;
}
  
// method returns number of pattern with 
// minimum m connection and maximum n connection
static int waysOfConnection(int m, int n)
{
    int [][]jump = new int[DOTS][DOTS];
  
    // 2 lies between 1 and 3
    jump[1][3] = jump[3][1] = 2;
  
    // 8 lies between 7 and 9
    jump[7][9] = jump[9][7] = 8;
  
    // 4 lies between 1 and 7
    jump[1][7] = jump[7][1] = 4;
  
    // 6 lies between 3 and 9
    jump[3][9] = jump[9][3] = 6;
  
    // 5 lies between 1, 9 2, 8 3, 7 and 4, 6
    jump[1][9] = jump[9][1] = jump[2][8] = 
                 jump[8][2] = jump[3][7] = 
                 jump[7][3] = jump[4][6] = 
                 jump[6][4] = 5;
  
    boolean []visit = new boolean[DOTS];
    int ways = 0;
    for (int i = m; i <= n; i++)
    {
        // 1, 3, 7, 9 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit, 
                                        jump, 1, i - 1);
  
        // 2, 4, 6, 8 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit,
                                        jump, 2, i - 1);
  
        ways += totalPatternFromCur(visit, 
                                    jump, 5, i - 1);
    }
    return ways;
}
  
// Driver Code
public static void main(String[] args) 
{
    int minConnect = 4;
    int maxConnect = 6;
  
    System.out.println(waysOfConnection(minConnect,
                                        maxConnect));
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to find number of ways
# to lock the mobile pattern
  
DOTS = 10;
  
# method to find total pattern starting from current cell
def totalPatternFromCur(visit, jump, cur, toTouch):
    if (toTouch <= 0):
          
        # if last cell then return 1 way
        if (toTouch == 0):
            return 1;
        else:
            return 0;
  
    ways = 0;
  
    # make this cell visited before
    # going to next call
    visit[cur] = True;
  
    for i in range(1, DOTS):
  
        '''
        * if this cell is not visit AND either i and cur are adjacent (then
        * jump[i][cur] = 0) or between cell must be visit already ( then
        * visit[jump[i][cur]] = 1)
        '''
        if (visit[i] == False and (jump[i][cur] == 0 or visit[jump[i][cur]])):
            ways += totalPatternFromCur(visit, jump, i, toTouch - 1);
  
    # make this cell not visited
    # after returning from call
    visit[cur] = False;
  
    return ways;
  
# method returns number of pattern with
# minimum m connection and maximum n connection
def waysOfConnection(m, n):
    jump = [[0 for i in range(DOTS)] for j in range(DOTS)];
  
    # 2 lies between 1 and 3
    jump[1][3] = jump[3][1] = 2;
  
    # 8 lies between 7 and 9
    jump[7][9] = jump[9][7] = 8;
  
    # 4 lies between 1 and 7
    jump[1][7] = jump[7][1] = 4;
  
    # 6 lies between 3 and 9
    jump[3][9] = jump[9][3] = 6;
  
    # 5 lies between 1, 9 2, 8 3, 7 and 4, 6
    jump[1][9] = jump[9][1] = jump[2][8] = jump[8][2] =\
        jump[3][7] = jump[7][3] = jump[4][6] = jump[6][4] = 5;
  
    visit = [False]*DOTS;
    ways = 0;
    for i in range(m, n + 1):
          
        # 1, 3, 7, 9 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit, jump, 1, i - 1);
  
        # 2, 4, 6, 8 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit, jump, 2, i - 1);
  
        ways += totalPatternFromCur(visit, jump, 5, i - 1);
  
    return ways;
  
# Driver Code
if __name__ == '__main__':
    minConnect = 4;
    maxConnect = 6;
  
    print(waysOfConnection(minConnect, maxConnect));
  
# This code is contributed by 29AjayKumar


C#
// C# program to find number of ways 
// to lock the mobile pattern
using System;
      
class GFG 
{
static int DOTS = 10;
  
// method to find total pattern starting from current cell
static int totalPatternFromCur(Boolean []visit, int [,]jump,
                                       int cur, int toTouch)
{
    if (toTouch <= 0)
    {
        // if last cell then return 1 way
        return (toTouch == 0) ? 1 : 0;
    }
  
    int ways = 0;
  
    // make this cell visited before 
    // going to next call
    visit[cur] = true;
  
    for (int i = 1; i < DOTS; i++)
    {
          
    /* if this cell is not visit AND
        either i and cur are adjacent (then jump[i,cur] = 0)
        or between cell must be visit already (
        then visit[jump[i,cur]] = 1) */
    if (!visit[i] && (jump[i, cur] == 0 || 
        visit[jump[i, cur]]))
        ways += totalPatternFromCur(visit, jump, 
                                    i, toTouch - 1);
    }
  
    // make this cell not visited
    // after returning from call
    visit[cur] = false;
  
    return ways;
}
  
// method returns number of pattern with 
// minimum m connection and maximum n connection
static int waysOfConnection(int m, int n)
{
    int [,]jump = new int[DOTS, DOTS];
   
    // 2 lies between 1 and 3
    jump[1, 3] = jump[3, 1] = 2;
  
    // 8 lies between 7 and 9
    jump[7, 9] = jump[9, 7] = 8;
  
    // 4 lies between 1 and 7
    jump[1, 7] = jump[7, 1] = 4;
  
    // 6 lies between 3 and 9
    jump[3, 9] = jump[9, 3] = 6;
  
    // 5 lies between 1, 9 2, 8 3, 7 and 4, 6
    jump[1, 9] = jump[9, 1] = jump[2, 8] = 
                 jump[8, 2] = jump[3, 7] = 
                 jump[7, 3] = jump[4, 6] = 
                 jump[6, 4] = 5;
  
    Boolean []visit = new Boolean[DOTS];
    int ways = 0;
    for (int i = m; i <= n; i++)
    {
        // 1, 3, 7, 9 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit, 
                                        jump, 1, i - 1);
  
        // 2, 4, 6, 8 are symmetric so multiplying by 4
        ways += 4 * totalPatternFromCur(visit,
                                        jump, 2, i - 1);
  
        ways += totalPatternFromCur(visit, 
                                    jump, 5, i - 1);
    }
    return ways;
}
  
// Driver Code
public static void Main(String[] args) 
{
    int minConnect = 4;
    int maxConnect = 6;
  
    Console.WriteLine(waysOfConnection(minConnect,
                                       maxConnect));
}
}
  
// This code is contributed by 29AjayKumar


输出:

34792