hdu1584 蜘蛛牌dfs

蜘蛛牌

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


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
 

Author
xhd
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1430  1732  1429  1495  1016 
思路:写在注释上了;
代码:
//这个题目不难,我的思路是 重建了一个图,map,使得没个点到每个点之间都有一条边,的权为他们的位置相减。这样可以节约很多时间
//然后就是dfs跑,用b数组 保存每个位置有哪些牌这里只用保存第一个和最后一个就行,其余的不用管。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int a[11];
int b[11][2];
int map[11][11];
int anf;
void dfs(int x,int y,int sum)
{
    sum+=map[x][y];
   b[y][1]=b[x][1];//移动了变换;
   b[x][0]=0;
   b[x][1]=0;
   //printf("%d %d %d %d %d\n",x,y,sum,b[y][0],b[y][1]);
   if(sum>anf) return ;
   if(b[10][0]==10&&b[10][1]==1) {anf=sum;return ;}

   //printf("aa\n");
    for(int i=1;i<=10;i++)
    {
       if(b[a[i]][0]==0) continue;
       if(b[a[i]][0]==10) continue;
       int u;
        for(int j=1;j<=10;j++)
       {
           if(b[j][1]==a[i]+1) {u=j;break;}
       }
       // printf("%d \n",u);
       int t0,t1,t3,t4;
       t0=b[a[i]][0],t1=b[a[i]][1];//这里用来回溯
       t3=b[u][0],t4=b[u][1];
      // printf("%tt %d %d %d %d \n",t0,t1,t3,t4);
       dfs(a[i],b[u][0],sum);
       b[a[i]][0]=t0,b[a[i]][1]=t1;
       b[u][0]=t3,b[u][1]=t4;
    }
    return ;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {   b[0][0]=b[0][1]=0;
        for(int i=1;i<=10;i++)
        {
            scanf("%d",&a[i]);
            b[i][0]=i;
            b[i][1]=i;
        }
        memset(map,0,sizeof(map));
        for(int i=1;i<=10;i++)
        {
            for(int j=1;j<=10;j++)
            {
                map[a[i]][a[j]]=abs(j-i);
                map[a[j]][a[i]]=abs(j-i);
            }
        }
        /*for(int i=1;i<=10;i++)
        {
            for(int j=1;j<=10;j++)
                printf("%d ",map[i][j]);
            printf("\n");
        }*/
        anf=999999999;
        dfs(0,0,0);
        printf("%d\n",anf);
    }
}



 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值