SRM 506(2-1000pt)

DIV2 1000pt

题意:一个由n*m的网格组成的棋盘,有四种点,'.'表示空点,'#'表示是墙不能走,'$'表示起点(同样是空点),'1'~'9'表示该点有复活时间为t的怪兽。每次,可以从一个点走到其上下左右的四个点,只要他们在棋盘上且不是墙,这样记为走了一步。如果走到的点有怪兽i,则杀死它,在杀死该怪兽以后,如果人又走了ti步(ti为该怪兽的复活时间)则该怪兽会复活,如果第ti步恰好走回到含有怪兽i的该点,则怪兽i会被再次杀死。问最少要多少步,才能使得整个棋盘上所有怪物同时处于死亡状态。如果不行,输出-1。

   n, m <= 50

解法:1、因为复活时间为1-9,所有最多有9个怪物。

   2、如果从这些已知的某个怪物出发,则最多有9!中可能的路径。

   所以得到解法,首先用BFS预处理出点'$'到所有怪物的最短距离,再预处理出每个怪物到其他怪物的最短距离,这一步时间复杂度最多O(10×50×50)。然后枚举出发的怪兽,求出从该怪兽出发,到使得所有怪物同时死亡所需要的最短时间,该时间加上'$'到出发怪兽的距离即为所求最短距离。  

   为了方便编码时处理怪兽复活问题,所以枚举出发怪兽的时候,可以写成枚举在哪个怪兽那里结束,然后倒推。

tag:BFS, DFS

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "SlimeXResidentSlime.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define CLR(x) memset(x, 0, sizeof(x))
 38 #define CLR1(x) memset(x, -1, sizeof(x))
 39 #define PB push_back
 40 #define MP make_pair
 41 #define SZ(v) ((int)(v).size())
 42 #define zero(x) (((x)>0?(x):-(x))<eps)
 43 #define out(x) cout<<#x<<":"<<(x)<<endl
 44 #define tst(a) cout<<#a<<endl
 45 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 46 
 47 typedef vector<int> VI;
 48 typedef vector<string> VS;
 49 typedef vector<double> VD;
 50 typedef long long int64;
 51 typedef pair<int, int> pii;
 52 
 53 const double eps = 1e-8;
 54 const double PI = atan(1.0)*4;
 55 const int maxint = 2139062143;
 56 
 57 struct bfs_nod{
 58     int x, y, d;
 59 };
 60 
 61 struct Nod{
 62     Nod(int xx, int yy, int cc){
 63         x = xx; y = yy; c = cc;
 64     }
 65     int x, y, c;
 66 };
 67 
 68 int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
 69 
 70 pii stt;
 71 int ans, n, m, nod_sz;
 72 map<pii, int> mp;
 73 bool v[100][100];
 74 bool vis[100];
 75 int d[20][20];
 76 vector<Nod> nod;
 77 VS A;
 78 bfs_nod an[10000];
 79 
 80 bool cmp(Nod a, Nod b)
 81 {
 82     return a.c < b.c;
 83 }
 84 
 85 bool ok(int x, int y)
 86 {
 87     if (x < 0 || y < 0) return 0;
 88     if (x >= n || y >= m) return 0;
 89     return A[x][y] != '#';
 90 }
 91 
 92 void BFS (int x, int y, int pos)
 93 {
 94     CLR (v);
 95     v[x][y] = 1;
 96 
 97     int l = 0, r = 0;
 98     bfs_nod tmp; tmp.d = 1;
 99     for (int i = 0; i < 4; ++ i) 
100         if (ok(x+dir[i][0], y+dir[i][1])){
101             int tx = x + dir[i][0], ty = y + dir[i][1];
102             if (v[tx][ty]) continue;
103             tmp.x = tx; tmp.y = ty;
104             v[tx][ty] = 1;
105             an[r++] = tmp;
106         }
107 
108     while (l < r){
109         tmp = an[l++];
110         if (mp.count(MP(tmp.x, tmp.y))){
111             int num = mp[MP(tmp.x, tmp.y)];
112             d[num][pos] = d[pos][num] = tmp.d;
113         }
114 
115         ++ tmp.d;
116         for (int i = 0; i < 4; ++ i)
117             if (ok(tmp.x+dir[i][0], tmp.y+dir[i][1])){
118                 bfs_nod tmp2 = tmp;
119                 int tx = tmp2.x + dir[i][0], ty = tmp2.y + dir[i][1];
120                 if (v[tx][ty]) continue;
121                 tmp2.x = tx; tmp2.y = ty;
122                 v[tx][ty] = 1;
123                 an[r++] = tmp2;
124             }
125     }
126 }
127 
128 void DFS (int p, int len, int num)
129 {
130     if (num == nod_sz){ 
131         if (d[10][p] > 0)
132             ans = min(ans, len + d[10][p]);
133         return ;
134     }
135     
136     vis[p] = 1;
137     for (int i = 0; i < nod_sz; ++ i)
138         if (!vis[i] && d[p][i] > 0 && len+d[p][i] < nod[i].c)
139             DFS (i, len+d[p][i], num+1);
140     vis[p] = 0;
141 }
142 
143 class SlimeXResidentSlime
144 {
145     public:
146         int exterminate(vector <string> AA){
147             A = AA;
148             n = A.size(); m = A[0].size();
149             nod.clear();
150             for (int i = 0; i < n; ++ i)
151                 for (int j = 0; j < m; ++ j){
152                     if (A[i][j] == '.' || A[i][j] == '#') continue;
153                     if (A[i][j] == '$'){
154                         stt.first = i; stt.second = j;
155                     }
156                     else
157                         nod.PB(Nod(i, j, A[i][j]-'0'));
158                 }
159             if (nod.size() > 9) return -1;
160             sort (nod.begin(), nod.end(), cmp);
161 
162             nod_sz = nod.size();
163             mp.clear();
164             for (int i = 0; i < nod_sz; ++ i)
165                 mp[make_pair(nod[i].x, nod[i].y)] = i;
166             mp[stt] = 10;
167 
168             CLR1 (d);
169             BFS (stt.first, stt.second, 10);
170             for (int i = 0; i < nod_sz; ++ i)
171                 BFS (nod[i].x, nod[i].y, i);
172 
173             ans = maxint;
174             for (int i = 0; i < nod_sz; ++ i){
175                 CLR (vis);
176                 DFS (i, 0, 1);
177             }
178             if (ans == maxint) return -1;
179             return ans;
180         }
181         
182 // BEGIN CUT HERE
183     public:
184     //void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
185     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0();}
186     private:
187     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
188     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
189     void test_case_0() { string Arr0[] = 
190 {".##.###..#....##.#.#......##...#.#....#####.#....#", "####..#####.####..#....###.#..######.##.#.#.##..##", ".##.#####.#.#####.#.###....#.##..##.##.#...######.", ".#.####.#..#.###.#.#....#.#.#.##.#.#..###..#.####.", "###.#.##....#..#..#.##..#####.####..##..#.#.#.#...", "....##.###...#####.#..#.######..####..#.##.#..###.", "######.##.#.##...#..#.#####..#..##.#.#.##.##.#....", "####.###..##.##.##..##..##.#####.#.####.#.##...###", "#.....#.###..#...#.###....#..#.#.#.##.#####.#....#", "###.###.##.#..#..###.###..##...#...#.##.#.####..#.", "..#....#..#..##.##...#....####.......#.####..#..##", ".#.....####.#.##.#.#.#..##.#.#.......####.$.###.##", "#####..#.#.##..#...##.#..##....#.##.##.#....##.###", "#.####...###.##.#..#.#....#.....#.#..###..#..##..#", ".#.##.#...########.#.......#..#..###.###.#.#.##.#.", ".##....#...##..##...#.#...#....##.##..#.....#.##..", "..##...###..#..#####..#.##..#.#.#..#.#....#.###.#.", ".####...##...#.##..#.#.#.#...###....######.....###", "#..##.###....#..###...####..#####.##.##.#.#..##...", "##...#..###..#.#.#.#.#...#.#.....###..#.#..#...###", "..#####.#.####..##.........##...###...#..###.#.###", "#.####.#..##....######..##.#.#...#..#..##..#.#...#", "...##.#..###....##.#.....#..#.#..#..##.#.....#...#", ".....#...#.#..###..##.##.....#.#..#.##.###.####.#.", ".#.#.#.#.####....#.##...#.###.###.#..#..#.###....#", ".#...#...#.....##.#..#.#...#.###..#...#.##.#..#.##", "#..##.#.##.##.####.##.##1.##...#.#...####..#.###.#", "#.##...###.##....####.##.###.##..##.#.#.#.#.#.....", ".......###...#.####....#..###..#.#.####...##.#####", "####..#..######........#..######.####.#...#.....##", "#######..#####...##..#.#...##..##..##.##.##.#...#.", "##..###.....#.#######..#.#...####....#.####.....##", "##.##...#.###.##.#.###...#....###....###..#####.#.", "#...#.###..#....#.###......#.#..##.#..##.....#.#.#", ".#.#.##..#..#..######.#.9...###.#.#..#.#####...#..", "#.##.#.###.####.###...#.#..####.....##.##.###...##", "#.....##.##....#######...#...#..#.##.#.#.##....###", "###.#.#.##.....#.#..###.#.#..#...##.##.###...##..#", "#.....##.#.#.####.#....##..##.#....##.##...#######", "..#...##..#.#####...#.#.##...##....#.#..#.#.#....#", "#.###...#####.##..##.##..##.###.####.#..#.#..#...#", "####.###...####.#..#..#....#.######.#.##.......#.#", "..#...#.....###....#####.##.##..#.#..#..##.##..#.#", ".###..##.#.#...###.#..#....##..#.#.#..#.#.##.#..##", ".####....#...##.##...###.##...########.#.....##.##", ".#.#######.###...#.....#.##..#.#..#####.#.##..##..", "#.##..#.##.##.####.#.#.#####...##.#.#.##.###...##.", ".###.#.#.#......####..##.##.#.#.#####.###.##...#..", ".#.#.#....#..#.#...#.#.....###...#...#.###......##", "#.##.###..###..#.#...#.######.#.##...##.#..#..####"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = -1; verify_case(0, Arg1, exterminate(Arg0)); }
191     void test_case_1() { string Arr0[] = {
192 "$",
193 "1",
194 "1"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = -1; verify_case(1, Arg1, exterminate(Arg0)); }
195     void test_case_2() { string Arr0[] = {
196 "$124"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 5; verify_case(2, Arg1, exterminate(Arg0)); }
197     void test_case_3() { string Arr0[] = {"$.#2"
198 ,"#..1"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 6; verify_case(3, Arg1, exterminate(Arg0)); }
199 
200 // END CUT HERE
201 
202 };
203 
204 // BEGIN CUT HERE
205 int main()
206 {
207     //freopen( "a.out" , "w" , stdout );    
208     SlimeXResidentSlime ___test;
209     ___test.run_test(-1);
210        return 0;
211 }
212 // END CUT HERE
View Code

 

posted @ 2013-12-12 01:03  Plumrain  阅读(267)  评论(0编辑  收藏  举报