UnsealTheSafe(TopCoder):解决方案背后的逻辑

时间:2013-05-30 05:02:46

标签: c++

      1 2 3
      4 5 6
      7 8 9 
      0 

保险柜的门被密码锁定。乔希亲眼目睹了一名员工打开保险箱。这是乔希发现的信息。

1.密码是一个恰好包含N位的序列..

2.使用下图所示的键盘输入密码。

3.密码中的每对相邻数字在键盘上相邻。键盘上的两个数字相邻,如果它们是不同的并且具有共同的边缘。

乔希有着打开保险箱的邪恶意图,但在他能够实现他的计划之前,他想知道有多少不同的密码存在。给定N的值,返回满足上面给出的所有约束的可能密码的数量。

解决方案:

    #include <cstdio> 
    class UnsealTheSafe{ 
    public: 
      long long countPasswords(int N){ 
        long long d[50][20]; 
        int i; 
        for(i=0; i<=9; i++){ 
          d[1][i]=1; 
        } 
        for(i=2; i<=N; i++){ 
          d[i][0]=d[i-1][7]; 
          d[i][1]=d[i-1][2]+d[i-1][4]; 
          d[i][2]=d[i-1][1]+d[i-1][3]+d[i-1][5]; 
          d[i][3]=d[i-1][2]+d[i-1][6]; 
          d[i][4]=d[i-1][1]+d[i-1][5]+d[i-1][7]; 
          d[i][5]=d[i-1][2]+d[i-1][4]+d[i-1][6]+d[i-1][8]; 
          d[i][6]=d[i-1][3]+d[i-1][5]+d[i-1][9]; 
          d[i][7]=d[i-1][4]+d[i-1][8]+d[i-1][0]; 
          d[i][8]=d[i-1][5]+d[i-1][7]+d[i-1][9]; 
          d[i][9]=d[i-1][6]+d[i-1][8]; 
          d[i][0]=d[i-1][7]; 
        } 
        long long ans=0; 
        for(i=0; i<=9; i++){ 
          ans+=d[N][i]; 
        } 
        return ans; 
      } 
    };

我无法理解此解决方案如何提供正确的结果。谁能告诉它背后的逻辑呢?

1 个答案:

答案 0 :(得分:0)

#include <cstdio> 
class UnsealTheSafe{ 
public: 
  long long countPasswords(int N){ 
    long long d[50][20]; // Create array to keep track of counts
                         // d[number of steps][final digit entered]
                         // (note: the choice of 50 and 20 appear arbitrary)
    int i; 
    for(i=0; i<=9; i++){ 
      d[1][i]=1; // This basically says that for each possible digit (0-9)
                 // there is 1 way to enter it in 1 step
    } 
    // Now for number of steps 2 and greater, fill in array
    // 
    for(i=2; i<=N; i++){ 
      d[i][0]=d[i-1][7];  // Because we can only get to 0 from 7
                          // the number of ways to get to 0 after i steps is 
                          // equal to the number of ways to get to 7 after 
                          // i-1 steps
      d[i][1]=d[i-1][2]+d[i-1][4]; // We can get to 1 after i steps by 
                                   // getting to 2 or 4 after i-1 steps
                                   // Thus the number of ways to get to 1
                                   // after i steps is equal to the number of
                                   // ways to get to 2 in i-1 steps plus
                                   // the number of ways to get to 4 in i-1 steps
      d[i][2]=d[i-1][1]+d[i-1][3]+d[i-1][5]; // etc.
      d[i][3]=d[i-1][2]+d[i-1][6]; 
      d[i][4]=d[i-1][1]+d[i-1][5]+d[i-1][7]; 
      d[i][5]=d[i-1][2]+d[i-1][4]+d[i-1][6]+d[i-1][8]; 
      d[i][6]=d[i-1][3]+d[i-1][5]+d[i-1][9]; 
      d[i][7]=d[i-1][4]+d[i-1][8]+d[i-1][0]; 
      d[i][8]=d[i-1][5]+d[i-1][7]+d[i-1][9]; 
      d[i][9]=d[i-1][6]+d[i-1][8]; 
      d[i][0]=d[i-1][7]; 
    } 
    long long ans=0; 
    for(i=0; i<=9; i++){ 
      ans+=d[N][i]; //the answer is the sume of the number of ways to 
                    // get to each digit in N steps, as we computed above
    } 
    return ans; 
  } 
};