zoukankan      html  css  js  c++  java
  • 蜘蛛牌(hdu 1584 DFS)

    蜘蛛牌

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2358    Accepted Submission(s): 1012

    传送门

    Problem Description
    蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。
     
    Input
    第一个输入数据是T,表示数据的组数。
    每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。
     
    Output
    对应每组数据输出最小移动距离。
     
    Sample Input
    1 1 2 3 4 5 6 7 8 9 10
     
    Sample Output
    9
    MY CODE:
     1 /*******************************
     2 
     3 Date    : 2015-12-06 21:05:48
     4 Author  : WQJ (1225234825@qq.com)
     5 Link    : http://www.cnblogs.com/a1225234/
     6 Name     : 
     7 
     8 ********************************/
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <cmath>
    13 #include <cstring>
    14 #include <string>
    15 #include <set>
    16 #include <vector>
    17 #include <queue>
    18 #include <stack>
    19 #define LL long long
    20 using namespace std;
    21 struct nod
    22 {
    23     bool f;
    24     int s,e;
    25 }a[11];
    26 int k;
    27 int m=0;
    28 int minstep=1000000;
    29 int co=0;
    30 void dfs(int step)
    31 {
    32     int i,j;
    33     if(step>minstep)    return;
    34     if(a[k].s==1)
    35     {
    36         if(step<minstep)
    37             minstep=step;
    38         return;
    39     }
    40     for(i=1;i<=10;i++)
    41     {
    42         if(a[i].e==10||a[i].f==0)    continue;
    43         for(j=1;j<=10;j++)
    44         {
    45             if(a[j].f&&i!=j&&a[i].e==(a[j].s-1))
    46             {
    47                 a[j].s=a[i].s;
    48                 a[i].f=0;
    49                 dfs(step+abs(i-j));
    50                 a[j].s=a[i].e+1;
    51                 a[i].f=1;
    52                 break;
    53             }
    54         }
    55     }
    56     return;
    57 }
    58 int main()
    59 {    
    60     freopen("in.txt","r",stdin);
    61     int T;
    62     int i,j;
    63     cin>>T;
    64     while(T--)
    65     {
    66         minstep=10000;
    67         for(i=1;i<=10;i++)
    68         {
    69             cin>>a[i].s;
    70             a[i].e=a[i].s;
    71             a[i].f=1;
    72             if(a[i].s==10)
    73                 k=i;
    74         }
    75         for(i=1;i<=10;i++)
    76         {
    77             if(a[i].e==10||a[i].f==0)    continue;
    78             for(j=1;j<=10;j++)
    79                 if(a[j].f==1&&i!=j&&a[i].e==(a[j].s-1))
    80                 {
    81                     a[j].s=a[i].s; 
    82                     a[i].f=0;
    83                     dfs(abs(i-j));
    84                     a[j].s=a[i].e+1;
    85                     a[i].f=1;
    86                     break;
    87                 }
    88         }
    89         cout<<minstep<<endl;
    90     }
    91     return 0;
    92 }

    百度的别的精简代码,数组存放的是位置,下标是牌。

     1 #include <iostream>
     2 using namespace std;
     3 int s,x[11],visit[11];
     4 int cmp(int a,int b)    //求绝对值
     5 {
     6     return a>b?a-b:b-a;
     7 }
     8 void dfs(int n,int step)
     9 {
    10     int i,j,k;
    11      if(n==9)
    12     {
    13         if(step<s)s=step;
    14         return;
    15     }
    16     for(i=0;i<10;i++)   //用来移动的牌
    17     if(!visit[i])
    18     for(j=i+1;j<10;j++) //移动到那个位置
    19     {
    20         if(!visit[j])
    21         {
    22             k=step+cmp(x[i],x[j]);
    23             if(k>=s)break;  //如果还没到终点就已经比先前的方案步数多,那么直接over
    24             visit[i]=1; //标记当前移动的牌已经就位了,因为i到了j的位置了,那么移动j就不管i的鸟事了
    25             dfs(n+1,k);
    26             visit[i]=0;
    27             break;
    28         }
    29     }
    30 }
    31 int main (void)
    32 {
    33     freopen("in.txt","r",stdin);
    34     int i,j,k,l,n,a;
    35     cin>>n;
    36     while(n--)
    37     {
    38         for(i=0;i<10;i++)
    39             cin>>a,x[a-1]=i,visit[i]=0; //用x记录每个牌出现的位置
    40         s=999999999;
    41         dfs(0,0);
    42         cout<<s<<endl;
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    POJ 2018 二分
    873. Length of Longest Fibonacci Subsequence
    847. Shortest Path Visiting All Nodes
    838. Push Dominoes
    813. Largest Sum of Averages
    801. Minimum Swaps To Make Sequences Increasing
    790. Domino and Tromino Tiling
    764. Largest Plus Sign
    Weekly Contest 128
    746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/a1225234/p/5025682.html
Copyright © 2011-2022 走看看