POJ 1099 -- Square Ice

POJ 1099 -- Square Ice

   字符处理题.
   根据所给 ASM 数据决定水分子的化学键形成方式. 这道题目乍一看不知道某一水分子周围的其他水分子的成键情况,差点冲动,一阵爆搜.
   仔细分析数据规模以及样例数据之后发现:ASM 为1或-1的水分子就是  Square Ice  的骨架,只要它们确定了,其他的水分子的成键就可以确定了.
   一个水分子以一个 oxygen atom 为中心,定能且只能与两个 hydrogen atom 成键,搭建好 ASM = 1, -1的水分子后,我的 第一思路 是:不妨设当前的需要成键的氧原子坐标为  O0 ( h0 ,  w0 ),设置增量集合为  D { ( Δh Δd ) | (-2, 0), (2, 0), (0, -2), (0, 2) },则待成键的四个 hydrogen atoms 的坐标就可以计算出来,即 O1 ( h0 + Δh , w0 + Δd ).
   由于成键数量为2,我只要定义一个 cnt = 0,当 verify_atom 并发现一个“可以用的” hydrogen atom,就++cnt,直到cnt = 2成立.  接着想想 verify_atom 这个函数应该怎么写?首先找到一个 hydrogen atom 的坐标,然后 verify: 上下是否有 ‘|’,左右是否有 ‘-’. 这样想想挺好,写完之后发现有问题,具体的错在什么地方留给大家思考. 所以对于 ASM = 0 的 atom,我发现它的成键方式只有四种,简言之就是:“上左”、“上右”、“下左”、“下右”,接下来枚举就行了,一旦成键成功马上调到下一个 atom,大功告成.
   题目很水,但是思路要很清晰,其中 draw_h2o 函数用了迭代开发的风格,我会在以后的文章中说说对于这种开发模式的心得. 最后给出代码.

  1  /*   http://poj.org/problem?id=1099   */
  2 
  3 #include <iostream>
  4 #include <cstring>
  5 
  6  using  namespace std;
  7 
  8  const  int Mmx = 13, Max = 1 << 7;
  9 
 10 inline  bool verify_atom( char h2o[Max][Max],  int atom_y,  int atom_x,  int height,  int width)
 11 {
 12      const  int dy[] = { -1, 0, 1, 0 }, dx[] = { 0, 1, 0, -1 };
 13      for ( int d = 0; d < 4; ++d)
 14     {
 15          int ny = atom_y + dy[d], nx = atom_x + dx[d];
 16          if (nx <= 0 && nx >= width - 1 && ny < 0 && ny >= height - 1)
 17              continue;
 18          if (h2o[ny][nx] == '|' || h2o[ny][nx] == '-')
 19              return  false;
 20     }
 21      return  true;
 22 }
 23 
 24 inline  void draw_h2o( int asmx[Mmx][Mmx],  char h2o[Max][Max],  int m)
 25 {
 26      const  int width = 2 * m + 1 + 2 * m + 2, height = 4 * m - 1;
 27 
 28      for ( int w = 0; w < width; ++w)
 29         h2o[0][w] = h2o[height - 1][w] = '*';
 30      for ( int h = 1; h < height - 1; ++h)
 31     {
 32          for ( int w = 0; w < width; ++w)
 33         {
 34              if (w == 0 || w == width - 1)
 35                 h2o[h][w] = '*';
 36              else
 37                 h2o[h][w] = ' ';
 38         }
 39     }    //  end: init h2o array
 40 
 41      for ( int h = 1; h < height - 1; h += 4)
 42     {
 43          for ( int w = 1; w < width - 1; w += 4)
 44             h2o[h][w] = 'H';
 45          for ( int w = 3; w < width - 1; w += 4)
 46             h2o[h][w] = 'O';
 47     }    //  end: draw 'h'-and-'o' line
 48 
 49      for ( int h = 3; h < height - 1; h += 4)
 50     {
 51          for ( int w = 3; w < width - 1; w += 4)
 52             h2o[h][w] = 'H';
 53     }     //  end: draw only-'h' line
 54 
 55      for ( int h = 1; h <= m; ++h)
 56     {
 57          for ( int w = 1; w <= m; ++w)
 58         {
 59              int oxygen_h = 1 + 4 * (h - 1), oxygen_w = 3 + 4 * (w - 1);
 60              if (asmx[h][w] == 1)
 61                 h2o[oxygen_h][oxygen_w - 1] = h2o[oxygen_h][oxygen_w + 1] = '-';
 62              if (asmx[h][w] == -1)
 63                 h2o[oxygen_h - 1][oxygen_w] = h2o[oxygen_h + 1][oxygen_w] = '|';
 64         }    //  end: draw h2o whose asmx equals 1 or -1
 65      }
 66 
 67      for ( int h = 1; h <= m; ++h)
 68     {
 69          for ( int w = 1; w <= m; ++w)  if (asmx[h][w] == 0)
 70         {
 71              int oxygen_h = 1 + 4 * (h - 1), oxygen_w = 3 + 4 * (w - 1);
 72              const  int dh[] = { -1, -1, 1, 1 }, dx[] = { -1, 1, -1, 1 };
 73              //  up-left up-right down-left down-right
 74               for ( int d = 0; d < 4; ++d)
 75             {
 76                  int y1 = oxygen_h + dh[d], x1 = oxygen_w, y2 = oxygen_h, x2 = oxygen_w + dx[d];
 77                  if (y1 <= 0 || y1 >= height - 1 || x1 <= 0 || x1 >= width - 1 || y2 <= 0 || y2 >= height - 1 || x2 <= 0 || x2 >= width - 1)
 78                      continue;
 79                  if (verify_atom(h2o, y1 + dh[d], x1, height, width) && verify_atom(h2o, y2, x2 + dx[d], height, width))
 80                 {
 81                     h2o[y1][x1] = '|';
 82                     h2o[y2][x2] = '-';
 83                      break;
 84                 }
 85             }
 86         }
 87     }    //  end: draw orthogonal h2o molecules (asmx = 0)
 88  }
 89 
 90 inline  void print_h2o( char h2o[Max][Max],  int m)
 91 {
 92      const  int width = 2 * m + 1 + 2 * m + 2, height = 4 * m - 1;
 93      for ( int h = 0; h < height; ++h)
 94     {
 95          for ( int w = 0; w < width; ++w)
 96             cout << h2o[h][w];
 97         cout << endl;
 98     }
 99 }
100 
101  int main()
102 {
103     ios::sync_with_stdio( false);
104      int m, cnt = 1;
105      for (;;)
106     {
107         cin >> m; 
108          if (m == 0)
109              break;
110          int asmx[Mmx][Mmx];
111          char h2o[Max][Max];
112         memset(h2o, '*',  sizeof(h2o));
113          for ( int h = 1; h <= m; ++h)
114         {
115              for ( int w = 1; w <= m; ++w)
116                 cin >> asmx[h][w];
117         }     //  end of input
118          cout << "Case " << cnt++ << ':' << endl << endl;
119         draw_h2o(asmx, h2o, m);
120         print_h2o(h2o, m);
121         cout << endl;
122     }
123 
124      return 0;
125 }
126 


你可能感兴趣的:(POJ 1099 -- Square Ice)