zoukankan      html  css  js  c++  java
  • hihocoder#1054 : 滑动解锁(深度优先搜索)

    描述

    滑动解锁是智能手机一项常用的功能。你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点。这些划过的点所组成的有向折线,如果与预设的折线在图案、方向上都一致,那么手机将解锁。两个点相邻当且仅当以这两个点为端点的线段上不存在尚未经过的点。此外,这条折线还需要至少经过4个点。

    为了描述方便,我们给这9个点从上到下、从左到右依次编号1-9。那么1->2->3是不合法的,因为长度不足。1->3->2->4也是合不法的,因为1->3穿过了尚未经过的点2。2->4->1->3->6是合法的,因为1->3时点2已经被划过了。

    作为一个爱逛知乎的好少年,小Hi已经知道一共有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等都是合法的方案。

    输入

    第一行包含一个整数T(1 <= T <= 10),代表测试数据组数。

    每个测试数据第一行是一个整数N(0 <= N <= 8),代表小Hi看到的折线段数目。

    以下N行每行包含两个整数X, Y (1 <= X, Y <= 9),代表小Hi看到点X和点Y是直接相连的。

    输出

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

    样例输入

    3  
    0  
    8  
    1 2  
    2 3  
    3 4  
    4 5  
    5 6  
    6 7  
    7 8  
    8 9  
    4  
    2 4  
    2 5   
    8 5  
    8 6  

    样例输出

    389112  
    2  
    258


    方法是利用深度优先搜索尝试所有可能,并累计符合的方案数,感觉效率很低啊,难道题目就是这样的意图?
     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 
     7 int test[10][10],vis[10],depth,aim_depth,n,res,es[10][10];
     8 
     9 
    10 int valid(int x,int y)
    11 {
    12     if((test[x][y]||test[y][x])&&!vis[(x+y)/2])
    13     {
    14         return 0;
    15     }
    16     return 1;
    17 }
    18 
    19 void dfs(int x,int depth,int e)
    20 {
    21     vis[x]=1;
    22     if(depth==aim_depth&&e==n)
    23     {
    24         ++res;
    25         return;
    26     }
    27     
    28     for(int i=1;i<10;++i)
    29     {
    30         if(!vis[i])
    31         {
    32             if(!valid(x,i))
    33             {
    34                 continue;
    35             }
    36             if(es[x][i])
    37             {
    38                 dfs(i,depth+1,e+1);
    39             }
    40             else
    41             {
    42                 dfs(i,depth+1,e);
    43             }
    44             vis[i]=0;
    45         }
    46     }    
    47 }
    48 
    49 int main()
    50 {
    51     memset(test,0,sizeof(test));
    52     test[1][3]=test[3][1]=test[1][7]=test[7][1]=1;
    53     test[2][8]=test[8][2]=test[4][6]=test[6][4]=1;
    54     test[1][9]=test[9][1]=test[3][7]=test[7][3]=1;
    55     test[9][3]=test[3][9]=test[9][7]=test[7][9]=1;
    56     
    57     int k,m,i,j;
    58     scanf("%d",&k);
    59     for(i=1;i<=k;i++)
    60     {
    61         res=0;
    62         memset(vis,0,sizeof(vis));
    63         memset(es,0,sizeof(es));
    64         
    65         cin>>n;
    66         
    67         if(n==0)
    68         {
    69             cout<<389112<<endl;
    70             continue;
    71         }
    72                 
    73         for(j=0;j<n;++j)
    74         {
    75             int a,b;
    76             cin>>a>>b;
    77             es[a][b]=es[b][a]=1;
    78         }
    79         
    80         aim_depth=max(4,n+1);
    81         
    82         for(;aim_depth<10;++aim_depth)
    83         {
    84             for(j=1;j<10;++j)
    85             {
    86                 dfs(j,1,0);
    87                 vis[j]=0;
    88             }            
    89         }
    90         cout<<res<<endl;
    91         
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    高格-远程支持中的奇怪问题【15】
    关于er图的几个工具
    如何解决win10明明是管理员还要权限的问题
    判断日期天数
    谈一谈在公司两次压测我总结的思路
    vue学习之-----v-model数据双向绑定,自定义组件父子传参
    Js各种小技巧总结
    openlayers学习之-----核心类
    openlayers学习之-----把坐标点改为WKT格式的数据
    新书介绍 -- 《Redis核心原理与实践》
  • 原文地址:https://www.cnblogs.com/Traveller-Leon/p/4843737.html
Copyright © 2011-2022 走看看