【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 105107
  • 排名 - 233

最新评论

阅读排行榜

评论排行榜

背景 Background
  话说上一回,晴天小猪不畏千难万险、千辛万苦、千磨万难……终于爬上了那座深山,来到了那位隐者的小屋中,但它不知道,有一个问题正等待着它……
  晴天小猪一推开门,就发现那里……空无一人?但在屋中央有一个石桌,上面有一些字(强吧),最大的几个:如要见我,先过了这道关再说!
  晴天小猪定睛一看,终于发现桌上密密麻麻布满了字,费了九天二猪之力,终于将题目看完,大意是:为了维护世界的和平……我们需要让九位勇士组成一个3*3的阵型去屠龙,但是这个阵型的要求很奇特,要九个人按照强弱依次编号1~9,且阵型中每行、每列、每条长对角线上的数字和都为15,这样才能使龙对勇士和阵型收到的损害最小,但九位勇士光是争夺名次就开始翻脸,各位**(任君想象)忙得不可开交,但晴天小猪也急得不可开交(-_-|||)),只好向你求助。

描述 Description
现在假设九位勇士已编好了号(感觉好像有人盯着我……)并站好了位置,例如:
7 8 9
1 2 3
4 5 6
每一次交换都可以将相邻的两位勇士(也就是编号……)交换位置,例如:
7 9 8
1 2 3  (8与9交换)
4 5 6

7 8 9
4 2 3  (4与1交换)
1 5 6
但不能
7 8 9
5 2 3  (1与5交换)
4 1 6
求最少的交换次数,使得九位勇士能在最短的时间内(当然是他们争完后……)以最安全的阵型去屠龙。
P.S:由于不能预测未来,各位**设想了许多的阵型(-_-||),所以给了你10组阵型(测试点),每组50个……

输入格式 Input Format
输入数据一共3*50行,每个数据中用3*3的9个不同的1~9的数字表示初始状态。
(样例就只给几个阵型了^_^)

输出格式 Output Format
每行一个数,即对应的初始阵型到所需阵型所需最少的交换次数,如果无解,输出-1。

分析:
BFS+康托展开.
1.对于每个成功的状态我们先算出它的康托展开,对于后面的BFS时就只需check是否是那些符合的状态即可,时间上快了很多。
2.对于那些搜索过的状态用个bool数组标记一下,费事再去搜索浪费时间。

【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<cstdlib>
#include
<iostream>
using namespace std;

const int hashnum[8]={69075,77577,135290,157121
,
205760,227591,285304,293806
};
const int F[10]={0,1,2,6,24,120,720,5040,40320,362880
};
struct
 node
{
    
int a[10
],dep;
} list[
400000
];
int hash[362890
];

void Swap(int &x,int &
y)
{
    
int t=x; x=y; y=
t;
}
int kangtuo(int *
a)
{
    
int k,num,s; bool bk[10
];
    memset(bk,
false,sizeof
(bk));
    s
=1; k=8
;
    
for (int i=1;i<=9;i++,k--
)
    {
        num
=0
;
        bk[a[i]]
=true
;
        
for (int j=1;j<=a[i]-1;j++
)
            
if (!bk[j]) num++
;
        s
+=num*
F[k];
    }
    
return
 s;
}
void
 bfs()
{
    
int
 head,tail,k;
    head
=tail=1; list[1].dep=0
;
    
while (head<=
tail)
    {
        
for (int i=1;i<=3;i++
)
            
for (int j=1;j<=2;j++
)
            {
                tail
++
;
                list[tail]
=
list[head];
                list[tail].dep
++
;
                Swap(list[tail].a[(i
-1)*3+j],list[tail].a[(i-1)*3+j+1
]);
                k
=
kangtuo(list[tail].a);
                
if (hash[k]==2
)
                {
                    printf(
"%d\n"
,list[tail].dep);
                    
return
 ;
                }
                
if (hash[k]==1) tail--
;
                hash[k]
=1
;
            }
        
for (int i=1;i<=2;i++
)
            
for (int j=1;j<=3;j++
)
            {
                tail
++
;
                list[tail]
=
list[head];
                list[tail].dep
++
;
                Swap(list[tail].a[(i
-1)*3+j],list[tail].a[i*3+
j]);
                k
=
kangtuo(list[tail].a);
                
if (hash[k]==2
)
                {
                    printf(
"%d\n"
,list[tail].dep);
                    
return
 ;
                }
                
if (hash[k]==1) tail--
;
                hash[k]
=1
;
            }
        head
++
;
    }
    printf(
"-1\n"
);
}
int
 main()
{
    
for (int i=1;i<=50;i++
)
    {
        
for (int i=1;i<=362880;i++) hash[i]=0
;
        
for (int i=0;i<=7;i++) hash[hashnum[i]]=2
;
        
for (int i=1;i<=9;i++) scanf("%d",&list[1
].a[i]);
        
int k=kangtuo(list[1
].a);
        
if (hash[k]==2
)
        {
            printf(
"0\n"
);
            
continue
;
        }
        bfs();
    }
    
return 0
;
}


 

posted on 2009-10-05 08:22 开拓者 阅读(544) 评论(0)  编辑 收藏 引用 所属分类: 算法&例题经典习题Vijos OJ

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理