Admiral(双向BFS + Hash)

简介: Problem Description Suppose that you are an admiral of a famous naval troop. Our naval forces have got 21 battleships.

Problem Description

Suppose that you are an admiral of a famous naval troop. Our naval forces have got 21 battleships. There are 6 types of battleships. First, we have got one flagship in which the admiral must be and it is denoted by number 0. Others are denoted by number from 1 to 5, each of them has 2, 3, 4, 5, 6 ships of its kind. So, we have got 21 battleships in total and we must take a giant battle against the enemy. Hence, the correct strategy of how to arrange each type of battleships is very important to us. The shape of the battlefield is like the picture that is shown below. To simplify the problem, we consider all battleships have the same rectangular shape. Fortunately, we have already known the optimal state of battleships. As you can see, the battlefield consists of 6 rows. And we have 6 types of battleship, so the optimal state is that all the battleships denoted by number i are located at the i-th row. Hence, each type of battleship corresponds to different color. You are given the initial state of battlefield as input. You can change the state of battlefield by changing the position of flagship with adjacent battleship. Two battleships are considered adjacent if and only if they are not in the same row and share parts of their edges. For example, if we denote the cell which is at i-th row and j-th position from the left as (i,j), then the cell (2,1) is adjacent to the cells (1,0), (1,1), (3,1), (3,2). Your task is to change the position of the battleships minimum times so as to reach the optimal state. Note: All the coordinates are 0-base indexed.

Input

The first line of input contains an integer T (1 <= T <= 10), the number of test cases.  Each test case consists of 6 lines. The i-th line of each test case contains i integers, denoting the type of battleships at i-th row of battlefield, from left to right.

Output

For each test case, if you can’t reach the goal in no more than 20 moves, you must output “too difficult” in one line. Otherwise, you must output the answer in one line.

SampleInput

1
1
2 0
2 1 2
3 3 3 3
4 4 4 4 4
5 5 5 5 5 5

SampleOutput

3

题意就是给你一个6*6的塔,上下两个相邻的单位可以进行交换,问最少进行几次交换,可以得到
0
1 1
2 2 2
3 3 3 3
……………………
这种状态,开始思路是用A*做,结果A*不是很熟练,没搞出来,写了个直接搜索炸了,然后我也是看了一下网上博客,使用双向搜索就行了。
思路就是从末尾开始往前搜索10步,从开始状态往后搜索10步,分别状态压缩一下存在map中,然后就看有没有两种相同的状态,否则就输出太难了。
代码:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 int fx[4][2] = {1,0,1,1,-1,-1,-1,0};    //左下,右下,左上,右上
 5 
 6 struct node{
 7     ll p[6][6];
 8     int r,c;
 9     int flag;
10     int step;
11 
12     node(){}
13     node(int _r,int _c,int _flag,int _step):r(_r),c(_c),flag(_flag),step(_step){}
14 };
15 
16 queue<node>q;
17 map<ll,ll>p[2];  //分别存储两个方向的bfs状态
18 
19 ll _hash(node a){  //用hash压缩路径状态
20     ll res = 0;
21     for(int i = 0; i < 6; i++){
22         for(int j = 0; j <= i; j++){
23             res = res*6 + a.p[i][j];
24         }
25     }
26     return res;
27 }
28 
29 int bfs(node &s,node &e){
30     while(!q.empty()){
31         q.pop();
32     }
33     p[0].clear();
34     p[1].clear();
35     q.push(s);
36     q.push(e);
37     p[s.flag][_hash(s)] = 0;  //必须要标记一下,因为后面会用到count函数查询是否存在
38     p[e.flag][_hash(e)] = 0;
39     while(!q.empty()){
40         node now = q.front();
41         q.pop();
42         ll sta = _hash(now);
43         if(p[!now.flag].count(sta)){
44             int num = p[!now.flag][sta] +  now.step;
45             if(num <= 20)
46                 return num;
47             else
48                 continue;
49         }
50 
51         if(now.step >= 10)  //处理10步即可
52             continue;
53         for(int i = 0; i < 4; i++){
54             node nxt = now;
55             nxt.step++;
56             nxt.r += fx[i][0];
57             nxt.c += fx[i][1];
58             if(nxt.r < 0 || nxt.r > 6 || nxt.c < 0 || nxt.c > nxt.r)
59                 continue;
60             swap(nxt.p[now.r][now.c],nxt.p[nxt.r][nxt.c]);
61             if(p[nxt.flag].count(_hash(nxt)) == 0)
62                 p[nxt.flag][_hash(nxt)] = nxt.step;
63             q.push(nxt);
64         }
65     }
66     return -1;
67 }
68 
69 int main(){
70     int t;
71     cin>>t;
72     node s, e;
73     while(t--){
74         for(int i = 0; i < 6; i++){
75             for(int j = 0; j <= i; j++){
76                 cin>>s.p[i][j];
77                 if(s.p[i][j] == 0)
78                     s.r = i, s.c = j;
79                 e.p[i][j] = i;
80             }
81         }
82         s.flag = 0;
83         s.step = 0;
84         e = node(0,0,1,0);
85         int ans = bfs(s,e);
86         if(ans >= 0 && ans <= 20)
87             cout << ans << endl;
88         else
89             cout << "too difficult" << endl;
90     }
91     return 0;
92 }
 
  

 

 
目录
相关文章
|
7天前
|
存储 负载均衡 算法
Hash介绍与应用详解
哈希算法在计算机科学中有着广泛而重要的应用,从数据存储、数据完整性校验到密码安全和分布式系统中的负载均衡,哈希函数都发挥着关键作用。通过本文的介绍和示例代码,希望您能更好地理解哈希的基本概念和实际应用,并在您的项目中有效地应用这些知识。
25 3
|
5月前
|
存储 缓存 搜索推荐
Hash Table
【6月更文挑战第12天】
31 1
|
6月前
|
Shell
|
存储 算法 安全
Hash 算法详细介绍与实现 (二)
书接上回,昨天写了第一部分,《Hash 算法详细介绍与实现 (一)》详细介绍了Hash表和Hash算法的相关概念以及算法的基本原理。同时简单介绍几种hash算法的实现:直接取余法和乘法取整法;本文接着详细唠唠Hash算法和Hash表这个数据结构的具体实现以及Hash算法和Hash表常见问题的解决方案,比如解决Hash表的冲突问题等等.相关的理论知识已在上篇文章详细介绍,这里就不再赘述,多的不说少的不唠,直接进入今天的主题:利用Hash算法实现Hash表
484 1
|
存储 算法
|
存储 算法
hash
一.什么是hash 百度百科上的定义是: 是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
104 0
|
前端开发 JavaScript
hash、chunkhash和contenthash
webpack 通用配置优化
129 0
hash、chunkhash和contenthash
|
存储 NoSQL Redis
|
存储 算法 安全
什么是 Hash 算法?
散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。
什么是 Hash 算法?