UESTC_Infected Land 2015 UESTC Training for Search Algorithm & String<Problem G>

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
...
[email protected]
...
3
.##
.#.
@##
3
##.
#..
@..
5
[email protected]
##...
#....
...#.
##.##
5
#...#
...#.
#....
...##
[email protected]
5
#....
.....
.....
.....
[email protected]
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 = 2807303;
const int MaxStatusSize = 2807303;
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[8][2] = {-1,0,1,0,0,-1,0,1,-1,-1,1,-1,-1,1,1,1};

int getval(const status &x,bool flag[][5] )
{
   for(int i = 0 ; i < n ; ++ i)
    for(int j = 0 ; j < n ; ++ j)
     if ((x.val>> (i*n+j)) & 1)
      flag[i][j] = true;
}

int gethashval(int x)
{
   return x % MaxHashSize;
}

inline bool inmap(int x,int y)
{
   if (x >= n || x < 0 || y >= n || y < 0)
    return false;
   return true;
}

void init_hash()
{
   memset(head,-1,sizeof(head));
}

bool insert(int id)
{
   int val = gethashval(st[id].val);
   int u = head[val];
   while(u != -1)
    {
       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[][5])
{
   for(int i = 0 ; i < n ; ++ i)
    {
        for(int j = 0 ; j < n ; ++ j)
         printf("%d",flag[i][j]);
        printf("\n");
    }
}

int bfs()
{
  int front = 0 , rear = 0;
  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 ^ (1 << (x*n+y))))
           return step;
          bool g[5][5];
          memset(g,false,sizeof(g));
          getval(ns,g);
          for(int i = 0 ; i < 8 ; ++ i)
           {
              int newx = x + dir[i][0];
              int newy = y + dir[i][1];
              if (!inmap(newx,newy) || g[newx][newy])
               continue;
              int newval = val;
              newval ^= (1 << (x*n+y));
              newval ^= (1 << (newx*n+newy));
              st[rear].step = step+1;
              st[rear].x = newx , st[rear].y = newy;
              g[newx][newy] = true;
              g[x][y] = false;
              for(int j = 0 ; j < n ; ++ j)
               for(int k = 0 ; k < n ; ++ k)
                {
                    if (j == newx && k == newy)
                     continue;
                    int cot = 0;
                    for(int z = 0 ; z < 8 ; ++ z)
                     {
                         int newr = j + dir[z][0];
                     int newt = k + dir[z][1];
                     if (!inmap(newr,newt))
                      continue;
                     if (g[newr][newt])
                      cot++;
                 }
                if (g[j][k])
                 {
                     if (cot != 2 && cot != 3)
                      newval &= ~(1<<(j*n+k));
                 }
                else
                 {
                     if (cot == 3)
                      newval |= (1<<(j*n+k));
                 }
             }
           g[x][y] = true;
           g[newx][newy] = false;
           st[rear].val = newval;
           if (insert(rear))
            {
                rear++;
            }

        }
   }
  return -1;
}

char buffer[15][15];

int main(int argc,char *argv[])
{
  while(scanf("%d",&n) && n)
   {
          for(int i = 0 ; i < n ; ++ i)
           scanf("%s",buffer[i]);
          init_hash();
          str.val = 0;
          for(int i = 0; i < n ; ++ i)
           for(int j = 0 ; j < n ; ++ j)
            {
                if (buffer[i][j] == ‘@‘)
                 str.x = i ,str.y = j,str.val |= (1<<(i*n+j));
                else if(buffer[i][j] == ‘#‘)
                 str.val |= (1<<(i*n+j));
         }
       str.step = 0;
       printf("%d\n",bfs());
   }
  return 0;
}
时间: 2024-10-24 22:40:06

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

UESTC_Palindromic String 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem M&gt;

M - Palindromic String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 128000/128000KB (Java/Others) Submit Status 秋实大哥喜欢探索新鲜事物,最近他发明了一种新型回文串,叫K重回文串!今天他想用它来考考小朋友们. 秋实大哥给出了与K重回文串有关的信息 任何字符串都属于0重回文串,包括空字符串. 一个长度为N的字符串S,S是K(k≥1)重回文串,当且仅当S是回文串,且其

UESTC_秋实大哥の恋爱物语 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem K&gt;

K - 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Submit Status 传说有这么一个故事! 在一个月白风清的晚上,秋实大哥约一位他心仪的妹子一起逛校园,浪漫的秋实大哥决定在当晚对妹子表白.“XXXXX...”,秋实大哥温情地说完了准备已久的话.而妹子决定用一种浪漫的方式接受秋实大哥(其实妹子早已对秋实大哥动心,这一刻她早已迫不及待了,但还是决定

UESTC_Eight Puzzle 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem F&gt;

F - Eight Puzzle Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sli

UESTC_韩爷的梦 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem N&gt;

N - 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limit: 1300/1300KB (Java/Others) Submit Status 一天,韩爷去百度面试,面试官给了他这么一个问题. 给你2万个字符串,每个字符串长度都是100,然后把2万个字符串丢入一个 set< string >g 中,问最终set里含有多少个元素? g 是一个用来存储字符串.具有去重功能的容器,即相同字符串在 g 中只能保留一个. 两个字符串相等,当且

UESTC_吴队长征婚 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem E&gt;

E - 吴队长征婚 Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 吴队长征婚这件事因为请客而没有传出去(虽然他忘了请一个队吃饭),于是吴队长高兴地玩起了木棒.吴队长拿了一些长度相同的木(guang)棒(gun),随机的把它们截成了N段,每一段最长50.现在他想把这些木棒还原成原来的状态,但是他忘记了原来的木棒有多少根,也忘记了每一根有多长.请帮助

UESTC_基爷的中位数 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem D&gt;

D - 基爷的中位数 Time Limit: 5000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 给你N个数,X1,X2,...,XN, 基爷让我们计算任意两个数差的绝对值 ∣Xi−Xj∣ (1≤i<j≤N) . 这样,我们可以得到 C2N 个数. 现在,基爷希望聪明的你能用一个简单的程序求出这 C2N 个数的中位数! Input 输入有多组数据. 每组数据,第一行一个整数 N

UESTC_基爷与加法等式 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem C&gt;

C - 基爷与加法等式 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 一天,上小学的妹妹跑过来问基爷一道字母加法等式,基爷不假思索的便给出了一组可行解. 聪明的你发现,一个字母等式可能有多种不同解,于是你想编个程序计算一下 Input 输入包含多组数据. 每组数据第一行一个整数n,表示有n个字符串 3 ≤ n ≤ 10 接下来n行,每行有1个最多只

UESTC_邱老师降临小行星 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem B&gt;

B - 邱老师降临小行星 Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65536/65535KB (Java/Others) Submit Status 人赢邱老师和任何男生比,都是不虚的.有一天,邱老师带妹子(们)来到了一个N行M列平面的小行星.对于每一个着陆地点,邱老师总喜欢带着妹子这样走:假设着陆地点为(r0, c0),那么他们下一步只能选择相邻格点,向四周走,即(r0–1, c0), (r0 + 1, c0), (r0

UESTC_全都是秋实大哥 2015 UESTC Training for Search Algorithm &amp; String&lt;Problem J&gt;

J - 全都是秋实大哥 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Submit Status 秋实大哥是一个多愁善感的人,偶尔也会唱唱两句伤情的歌.每次唱完后,秋实大哥都能解决一道问题!这次也不例外. 秋实大哥告诉了你 一些关于这个问题的信息 如果一个字符串S是由若干个子串a连续拼接而成的,则称a是S的循环节,即A=a+a+...+a.比如 aba 是 abaabaaba