博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SRM 506(2-1000pt)
阅读量:6816 次
发布时间:2019-06-26

本文共 8550 字,大约阅读时间需要 28 分钟。

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 
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #include
26 #include
27 #include
28 #include
29 #include
30 #include
31 #include
32 #include
33 #include
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))
VI; 48 typedef vector
VS; 49 typedef vector
VD; 50 typedef long long int64; 51 typedef pair
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
mp; 73 bool v[100][100]; 74 bool vis[100]; 75 int d[20][20]; 76 vector
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 SlimeXResidentSlime144 {145 public:146 int exterminate(vector
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 else157 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 HERE183 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
string print_array(const vector
&V) { ostringstream os; os << "{ "; for (typename vector
::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
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
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
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
Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 6; verify_case(3, Arg1, exterminate(Arg0)); }199 200 // END CUT HERE201 202 };203 204 // BEGIN CUT HERE205 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

 

转载于:https://www.cnblogs.com/plumrain/p/srm_506.html

你可能感兴趣的文章
XWifiMouse早期写的一个Android鼠标App
查看>>
postgres预写式日志的内核实现详解-wal记录写入
查看>>
用面向接口编程思想看找对象
查看>>
OC文件操作习题
查看>>
Nginx常用命令
查看>>
TWaver GIS在电信中的使用
查看>>
几款程序员常用的辅助编程工具
查看>>
Python struct处理二进制
查看>>
FlashSwing教你如何布置组件
查看>>
字符串合并
查看>>
spring定时器配置
查看>>
脑机连接——辫子
查看>>
xmanager报错处理
查看>>
JS常用例子
查看>>
redis学习笔记---redis主从复制
查看>>
InstallShield 常用常量
查看>>
Android Intent的几种用法全面总结
查看>>
发布一个打飞机游戏
查看>>
Websocket 与 Socket.IO、Socket
查看>>
virtualization technology设置
查看>>