G - Infected Land

Time Limit: 6000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit Status

The earth is under an attack of a deadly virus. Luckily, prompt actions of the Ministry of Health against this emergency successfully confined the spread of the infection within a square grid of areas. Recently, public health specialists found an interesting pattern with regard to the transition of infected areas. At each step in time, every area in the grid changes its infection state according to infection states of its directly (horizontally, vertically, and diagonally) adjacent areas.

  • An infected area continues to be infected if it has two or three adjacent infected areas.
  • An uninfected area becomes infected if it has exactly three adjacent infected areas.
  • An area becomes free of the virus, otherwise.

Your mission is to fight against the virus and disinfect all the areas. The Ministry of Health lets an anti-virus vehicle prototype under your command. The functionality of the vehicle is summarized as follows.

At the beginning of each time step, you move the vehicle to one of the eight adjacent areas. The vehicle is not allowed to move to an infected area (to protect its operators from the virus). It is not allowed to stay in the same area.

Following vehicle motion, all the areas, except for the area where the vehicle is in, change their infection states according to the transition rules described above.

Special functionality of the vehicle protects its area from virus infection even if the area is adjacent to exactly three infected areas. Unfortunately, this virus-protection capability of the vehicle does not last. Once the vehicle leaves the area, depending on the infection states of the adjacent areas, the area can be infected.

The area where the vehicle is in, which is uninfected, has the same effect to its adjacent areas as an infected area as far as the transition rules are concerned. The following series of figures illustrate a sample scenario that successfully achieves the goal.

Initially, your vehicle denoted by @ is found at (1,5) in a 5×5-grid of areas, and you see some infected areas which are denoted by #'s.

Firstly, at the beginning of time step 1, you move your vehicle diagonally to the southwest, that is, to the area (2,4). Note that this vehicle motion was possible because this area was not infected at the start of time step 1.

Following this vehicle motion, infection state of each area changes according to the transition rules. The column "1-end" of the figure illustrates the result of such changes at the end of time step 1. Note that the area (3,3) becomes infected because there were two adjacent infected areas and the vehicle was also in an adjacent area, three areas in total.

In time step 2, you move your vehicle to the west and position it at (2,3).

Then infection states of other areas change. Note that even if your vehicle had exactly three infected adjacent areas (west, southwest, and south), the area that is being visited by the vehicle is not infected. The result of such changes at the end of time step 2 is as depicted in "2-end".

Finally, in time step 3, you move your vehicle to the east. After the change of the infection states, you see that all the areas have become virus free! This completely disinfected situation is the goal. In the scenario we have seen, you have successfully disinfected all the areas in three time steps by commanding the vehicle to move (1) southwest, (2) west, and (3) east.

Your mission is to find the length of the shortest sequence(s) of vehicle motion commands that can successfully disinfect all the areas.

Input

The input is a sequence of datasets. The end of the input is indicated by a line containing a single zero. Each dataset is formatted as sample input.

Here, n is the size of the grid. That means that the grid is comprised of n×n areas. You may assume 1≤n≤5. The rest of the dataset consists of n lines of n letters. Each letter aij specifies the state of the area at the beginning: # for infection, . for free of virus, and @ for the initial location of the vehicle. The only character that can appear in a line is #., or @. Among n × n areas, there exists exactly

Output

For each dataset, output the minimum number of time steps that is required to disinfect all the areas. If there exists no motion command sequence that leads to complete disinfection, output−1. The output should not contain any other extra character.

Sample input and output

Sample Input Sample Output
3
...
.@.
...
3
.##
.#.
@##
3
##.
#..
@..
5
....@
##...
#....
...#.
##.##
5
#...#
...#.
#....
...##
..@..
5
#....
.....
.....
.....
..@..
5
#..#.
#.#.#
.#.#.
....#
.#@##
5
..##.
..#..
#....
#....
.#@..
0
0
10
-1
3
2
1
6
4

解题报告

这是一道二进制状态压缩搜索题目,地图大小最大是 5*5 ,每个点只有感染和不感染两种状态,用一个int即可存下.

之后考虑判重,因为int太大,其实我们用到的状态并没有那么多,故我们采用哈希表来判重.

唯一需要注意的是医疗车本身也看成感染的点....

#include <iostream>
#include <cstring>
#include <cstdio> using namespace std;
const int MaxHashSize = ;
const int MaxStatusSize = ;
typedef struct status
{
int x,y,val,step;
}; status str;
int n;
int head[MaxHashSize];
int new_next[MaxStatusSize];
status st[MaxStatusSize];
status q[MaxStatusSize];
int dir[][] = {-,,,,,-,,,-,-,,-,-,,,}; int getval(const status &x,bool flag[][] )
{
for(int i = ; i < n ; ++ i)
for(int j = ; j < n ; ++ j)
if ((x.val>> (i*n+j)) & )
flag[i][j] = true;
} int gethashval(int x)
{
return x % MaxHashSize;
} inline bool inmap(int x,int y)
{
if (x >= n || x < || y >= n || y < )
return false;
return true;
} void init_hash()
{
memset(head,-,sizeof(head));
} bool insert(int id)
{
int val = gethashval(st[id].val);
int u = head[val];
while(u != -)
{
if (st[id].val == st[u].val && st[id].x == st[u].x && st[id].y == st[u].y)
return false;
u = new_next[u];
}
new_next[id] = head[val];
head[val] = id;
return true;
} void dump(bool flag[][])
{
for(int i = ; i < n ; ++ i)
{
for(int j = ; j < n ; ++ j)
printf("%d",flag[i][j]);
printf("\n");
}
} int bfs()
{
int front = , rear = ;
st[rear] = str;
insert(rear++);
while(front < rear)
{
status &ns = st[front++];
int x = ns.x , y = ns.y , val = ns.val , step = ns.step;
if ( !(val ^ ( << (x*n+y))))
return step;
bool g[][];
memset(g,false,sizeof(g));
getval(ns,g);
for(int i = ; i < ; ++ i)
{
int newx = x + dir[i][];
int newy = y + dir[i][];
if (!inmap(newx,newy) || g[newx][newy])
continue;
int newval = val;
newval ^= ( << (x*n+y));
newval ^= ( << (newx*n+newy));
st[rear].step = step+;
st[rear].x = newx , st[rear].y = newy;
g[newx][newy] = true;
g[x][y] = false;
for(int j = ; j < n ; ++ j)
for(int k = ; k < n ; ++ k)
{
if (j == newx && k == newy)
continue;
int cot = ;
for(int z = ; z < ; ++ z)
{
int newr = j + dir[z][];
int newt = k + dir[z][];
if (!inmap(newr,newt))
continue;
if (g[newr][newt])
cot++;
}
if (g[j][k])
{
if (cot != && cot != )
newval &= ~(<<(j*n+k));
}
else
{
if (cot == )
newval |= (<<(j*n+k));
}
}
g[x][y] = true;
g[newx][newy] = false;
st[rear].val = newval;
if (insert(rear))
{
rear++;
} }
}
return -;
} char buffer[][]; int main(int argc,char *argv[])
{
while(scanf("%d",&n) && n)
{
for(int i = ; i < n ; ++ i)
scanf("%s",buffer[i]);
init_hash();
str.val = ;
for(int i = ; i < n ; ++ i)
for(int j = ; j < n ; ++ j)
{
if (buffer[i][j] == '@')
str.x = i ,str.y = j,str.val |= (<<(i*n+j));
else if(buffer[i][j] == '#')
str.val |= (<<(i*n+j));
}
str.step = ;
printf("%d\n",bfs());
}
return ;
}

UESTC_Infected Land 2015 UESTC Training for Search Algorithm & String<Problem G>的更多相关文章

  1. UESTC_韩爷的梦 2015 UESTC Training for Search Algorithm & String<Problem N>

    N - 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limit: 1300/1300KB (Java/Others) Submit Stat ...

  2. UESTC_Palindromic String 2015 UESTC Training for Search Algorithm & String<Problem M>

    M - Palindromic String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 128000/128000KB (Java ...

  3. UESTC_秋实大哥の恋爱物语 2015 UESTC Training for Search Algorithm & String<Problem K>

    K - 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Su ...

  4. UESTC_Eight Puzzle 2015 UESTC Training for Search Algorithm & String<Problem F>

    F - Eight Puzzle Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) ...

  5. UESTC_吴队长征婚 2015 UESTC Training for Search Algorithm & String<Problem E>

    E - 吴队长征婚 Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  6. UESTC_基爷的中位数 2015 UESTC Training for Search Algorithm & String<Problem D>

    D - 基爷的中位数 Time Limit: 5000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. UESTC_基爷与加法等式 2015 UESTC Training for Search Algorithm & String<Problem C>

    C - 基爷与加法等式 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  8. UESTC_邱老师降临小行星 2015 UESTC Training for Search Algorithm & String<Problem B>

    B - 邱老师降临小行星 Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65536/65535KB (Java/Others) Su ...

  9. UESTC_Ferris Wheel String 2015 UESTC Training for Search Algorithm & String<Problem L>

    L - Ferris Wheel String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 43000/43000KB (Java/ ...

随机推荐

  1. c++ 03

    一.面向对象编程 1.什么是对象?什么是对象编程? 1)万物皆对象 2)世界是由一组相互之间紧密联系的对象组成的. 3)通过将对象按照属性和行为共性进行分类,达到将具体事物进行抽象的效果. 4)通过程 ...

  2. HDU 1394 Minimum Inversion Number(线段树 或 树状数组)

    题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...

  3. YYmodel 郭耀源 底层分析

    http://www.tuicool.com/articles/meAzIny         YYModel 简介与使用 http://www.jianshu.com/p/663c7b608ff5 ...

  4. IOS6和IOS7 显示一样的SearchBar

    if (isIOS7) { mySearchBar=[[UISearchBar alloc]initWithFrame:CGRectMake(, , , )]; mySearchBar.autocor ...

  5. Linux查看系统信息

    系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...

  6. python学习之路-11 多线程、多进程、协程

    python内置队列模块 queue queue的四种队列 q = queue.Queue() # 先进先出队列 q = queue.LifoQueue() # 后进先出队列 q = queue.Pr ...

  7. 格而知之16:我所理解的Block(3)

    23.在前文中的例子中,Block结构体里的isa指针还没有详细讲解,这个指针都被置向了_NSConcreteStackBlock,它标识了Block的类型. 其实除了_NSConcreteStack ...

  8. python实现二叉树和它的七种遍历

    介绍: 树是数据结构中很重要的一种,基本的用途是用来提高查找效率,对于要反复查找的情况效果更佳,如二叉排序树.FP-树. 另外能够用来提高编码效率,如哈弗曼树. 代码: 用python实现树的构造和几 ...

  9. 《TCP/IP具体解释卷2:实现》笔记--4种不同类型的mbuf

    mbuf的主要用途是保存子进程和网络接口间互相传递的用户数据.但mbuf也用于保存其它各种数据:源于目的地址.插口 选项等等. 以下介绍我们要遇到的四种类型的mbuf,它们根据在成员m_flag中填写 ...

  10. Android日志系统Logcat源代码简要分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6606957 在前面两篇文章Android日志系 ...