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

 // BEGIN CUT HERE
/*
* Author: plum rain
* score :
*/
/* */
// END CUT HERE
#line 11 "SlimeXResidentSlime.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <queue>
#include <bitset>
#include <list>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define CLR1(x) memset(x, -1, sizeof(x))
#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define zero(x) (((x)>0?(x):-(x))<eps)
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64;
typedef pair<int, int> pii; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; struct bfs_nod{
int x, y, d;
}; struct Nod{
Nod(int xx, int yy, int cc){
x = xx; y = yy; c = cc;
}
int x, y, c;
}; int dir[][] = {{-, }, {, }, {, -}, {, }}; pii stt;
int ans, n, m, nod_sz;
map<pii, int> mp;
bool v[][];
bool vis[];
int d[][];
vector<Nod> nod;
VS A;
bfs_nod an[]; bool cmp(Nod a, Nod b)
{
return a.c < b.c;
} bool ok(int x, int y)
{
if (x < || y < ) return ;
if (x >= n || y >= m) return ;
return A[x][y] != '#';
} void BFS (int x, int y, int pos)
{
CLR (v);
v[x][y] = ; int l = , r = ;
bfs_nod tmp; tmp.d = ;
for (int i = ; i < ; ++ i)
if (ok(x+dir[i][], y+dir[i][])){
int tx = x + dir[i][], ty = y + dir[i][];
if (v[tx][ty]) continue;
tmp.x = tx; tmp.y = ty;
v[tx][ty] = ;
an[r++] = tmp;
} while (l < r){
tmp = an[l++];
if (mp.count(MP(tmp.x, tmp.y))){
int num = mp[MP(tmp.x, tmp.y)];
d[num][pos] = d[pos][num] = tmp.d;
} ++ tmp.d;
for (int i = ; i < ; ++ i)
if (ok(tmp.x+dir[i][], tmp.y+dir[i][])){
bfs_nod tmp2 = tmp;
int tx = tmp2.x + dir[i][], ty = tmp2.y + dir[i][];
if (v[tx][ty]) continue;
tmp2.x = tx; tmp2.y = ty;
v[tx][ty] = ;
an[r++] = tmp2;
}
}
} void DFS (int p, int len, int num)
{
if (num == nod_sz){
if (d[][p] > )
ans = min(ans, len + d[][p]);
return ;
} vis[p] = ;
for (int i = ; i < nod_sz; ++ i)
if (!vis[i] && d[p][i] > && len+d[p][i] < nod[i].c)
DFS (i, len+d[p][i], num+);
vis[p] = ;
} class SlimeXResidentSlime
{
public:
int exterminate(vector <string> AA){
A = AA;
n = A.size(); m = A[].size();
nod.clear();
for (int i = ; i < n; ++ i)
for (int j = ; j < m; ++ j){
if (A[i][j] == '.' || A[i][j] == '#') continue;
if (A[i][j] == '$'){
stt.first = i; stt.second = j;
}
else
nod.PB(Nod(i, j, A[i][j]-''));
}
if (nod.size() > ) return -;
sort (nod.begin(), nod.end(), cmp); nod_sz = nod.size();
mp.clear();
for (int i = ; i < nod_sz; ++ i)
mp[make_pair(nod[i].x, nod[i].y)] = i;
mp[stt] = ; CLR1 (d);
BFS (stt.first, stt.second, );
for (int i = ; i < nod_sz; ++ i)
BFS (nod[i].x, nod[i].y, i); ans = maxint;
for (int i = ; i < nod_sz; ++ i){
CLR (vis);
DFS (i, , );
}
if (ans == maxint) return -;
return ans;
} // BEGIN CUT HERE
public:
//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(); }
void run_test(int Case) { if ((Case == -) || (Case == )) test_case_0();}
private:
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(); }
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; } }
void test_case_0() { string Arr0[] =
{".##.###..#....##.#.#......##...#.#....#####.#....#", "####..#####.####..#....###.#..######.##.#.#.##..##", ".##.#####.#.#####.#.###....#.##..##.##.#...######.", ".#.####.#..#.###.#.#....#.#.#.##.#.#..###..#.####.", "###.#.##....#..#..#.##..#####.####..##..#.#.#.#...", "....##.###...#####.#..#.######..####..#.##.#..###.", "######.##.#.##...#..#.#####..#..##.#.#.##.##.#....", "####.###..##.##.##..##..##.#####.#.####.#.##...###", "#.....#.###..#...#.###....#..#.#.#.##.#####.#....#", "###.###.##.#..#..###.###..##...#...#.##.#.####..#.", "..#....#..#..##.##...#....####.......#.####..#..##", ".#.....####.#.##.#.#.#..##.#.#.......####.$.###.##", "#####..#.#.##..#...##.#..##....#.##.##.#....##.###", "#.####...###.##.#..#.#....#.....#.#..###..#..##..#", ".#.##.#...########.#.......#..#..###.###.#.#.##.#.", ".##....#...##..##...#.#...#....##.##..#.....#.##..", "..##...###..#..#####..#.##..#.#.#..#.#....#.###.#.", ".####...##...#.##..#.#.#.#...###....######.....###", "#..##.###....#..###...####..#####.##.##.#.#..##...", "##...#..###..#.#.#.#.#...#.#.....###..#.#..#...###", "..#####.#.####..##.........##...###...#..###.#.###", "#.####.#..##....######..##.#.#...#..#..##..#.#...#", "...##.#..###....##.#.....#..#.#..#..##.#.....#...#", ".....#...#.#..###..##.##.....#.#..#.##.###.####.#.", ".#.#.#.#.####....#.##...#.###.###.#..#..#.###....#", ".#...#...#.....##.#..#.#...#.###..#...#.##.#..#.##", "#..##.#.##.##.####.##.##1.##...#.#...####..#.###.#", "#.##...###.##....####.##.###.##..##.#.#.#.#.#.....", ".......###...#.####....#..###..#.#.####...##.#####", "####..#..######........#..######.####.#...#.....##", "#######..#####...##..#.#...##..##..##.##.##.#...#.", "##..###.....#.#######..#.#...####....#.####.....##", "##.##...#.###.##.#.###...#....###....###..#####.#.", "#...#.###..#....#.###......#.#..##.#..##.....#.#.#", ".#.#.##..#..#..######.#.9...###.#.#..#.#####...#..", "#.##.#.###.####.###...#.#..####.....##.##.###...##", "#.....##.##....#######...#...#..#.##.#.#.##....###", "###.#.#.##.....#.#..###.#.#..#...##.##.###...##..#", "#.....##.#.#.####.#....##..##.#....##.##...#######", "..#...##..#.#####...#.#.##...##....#.#..#.#.#....#", "#.###...#####.##..##.##..##.###.####.#..#.#..#...#", "####.###...####.#..#..#....#.######.#.##.......#.#", "..#...#.....###....#####.##.##..#.#..#..##.##..#.#", ".###..##.#.#...###.#..#....##..#.#.#..#.#.##.#..##", ".####....#...##.##...###.##...########.#.....##.##", ".#.#######.###...#.....#.##..#.#..#####.#.##..##..", "#.##..#.##.##.####.#.#.#####...##.#.#.##.###...##.", ".###.#.#.#......####..##.##.#.#.#####.###.##...#..", ".#.#.#....#..#.#...#.#.....###...#...#.###......##", "#.##.###..###..#.#...#.######.#.##...##.#..#..####"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[]))); int Arg1 = -; verify_case(, Arg1, exterminate(Arg0)); }
void test_case_1() { string Arr0[] = {
"$",
"",
""}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[]))); int Arg1 = -; verify_case(, Arg1, exterminate(Arg0)); }
void test_case_2() { string Arr0[] = {
"$124"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[]))); int Arg1 = ; verify_case(, Arg1, exterminate(Arg0)); }
void test_case_3() { string Arr0[] = {"$.#2"
,"#..1"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[]))); int Arg1 = ; verify_case(, Arg1, exterminate(Arg0)); } // END CUT HERE }; // BEGIN CUT HERE
int main()
{
//freopen( "a.out" , "w" , stdout );
SlimeXResidentSlime ___test;
___test.run_test(-);
return ;
}
// END CUT HERE

SRM 506(2-1000pt)的更多相关文章

  1. TC250专场

    SRM 623 DIV2 1000pt 题意:给出一个最多50*50的矩阵,每个单元可能为'.'.'P'.'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形 ...

  2. SRM149 - SRM150(少SRM150-DIV1-LV3)

    SRM 149 DIV2 1000pt 题意: 对于n个人,第i人有pi的钱.将他们分成不超过四个组,每组统一交费x,对每个人,若他拥有的钱超过x则交费,否则不交费.问最多能使这些人交多少钱. 1&l ...

  3. Topcoder 好题推荐

    SRM SRM147 DIV1 1000pt DP SRM148 DIV1 1100pt 递归 SRM149 DIV1 1000pt math SRM150 DIV1 500pt DP SRM469 ...

  4. SRM144 - SRM 148(少144-DIV1-LV3,147-DIV2-LV3)

    SRM 144 DIV 1 500pt tag:组合 题意:彩票中奖.给定n, m,从1-n中选择m个数组成数列a1, a2, a3...am.对于数列{am}分别满足以下条件的概率: (1)数列所有 ...

  5. SRM 508(2-1000pt)

    DIV2 1000pt 题意:给定整数n和r,求有多少个这样的数列,a1,a2...an,使得a1 + a2 +...+an = a1|a2|a3|...|an,(按位或).输出这样数列的个数mod  ...

  6. PIC12F508/505/509/510/506/519/526/527单片机破解芯片解密方法!

    IC芯片解密PIC12F508/505/509/510/506/519/526/527单片机破解 单片机芯片解密型号: PIC12F508解密 | PIC12F505解密 | PIC12F506解密  ...

  7. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  8. SRM 513 2 1000CutTheNumbers(状态压缩)

    SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as St ...

  9. SRM 510 2 250TheAlmostLuckyNumbersDivTwo(数位dp)

    SRM 510 2 250TheAlmostLuckyNumbersDivTwo Problem Statement John and Brus believe that the digits 4 a ...

随机推荐

  1. c# 双问号运算

    model.id??0 ??运算:如果运算符左边的值为NULL侧返回右边的值,否则返回左边的值

  2. app图标和启动页设置

    弄了一下午,终于把iOS中图标的设置和启动页的设置弄明白了.我想以后再也不会浑了. 进入正题: 一:apple 1).iPhone4s 3.5寸屏,也就是640*960,但在模拟器上正常用的是320* ...

  3. javascript基础学习(九)

    javascript之基本包装类型 学习要点: 基本包装类型概述 Boolean类型 Number类型 String类型 一.基本包装类型概述 为了便于操作基本类型值,提供了3种特殊的引用类型:Boo ...

  4. HttpClient的get+post请求使用

    啥都不说,先上代码 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReade ...

  5. Linux查看进程内存占用及内存使用情况

    LINUX进程内存占用查看方法(1)top可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:$ top ...

  6. 将listBox中信息显示在dataGridview中,操作datagridview后删除listBox信息和SQL数据库信息 续(浅谈listBox..)

    应用场景      对datagridview控件使用了解,以及操作datagridview选中的信息删除,并且有二次确认后才删除用户信息.相应的删除listbox中用户信息,下面一起看看需要哪些准备 ...

  7. c#抽象工厂模式

    抽象工厂模式向客户端提供一个接口,使得客户端在不必指定具体类型的情况下,创建多个产品族中的对象.本文采取的仍然是接着以前的那个快餐店的例子. 现在,快餐店经常良好,逐渐发展壮大,为了适合不同地方人的饮 ...

  8. Invoke()/BeginInvoke()区别

    查看MSDN如下: Control..::.Invoke          ---> 在拥有此控件的基础窗口句柄的线程上执行委托. Control..::.BeginInvoke  ---> ...

  9. js 强制转换

    强制转换为布尔类型: <script> var text =Boolean(0) //=>以下转换的类型都为false text = Boolean(0.0) text = Bool ...

  10. 织梦dedecms后台发布文章不自动更新首页与栏目列表页

    dedecms发文章不自动更新首页也列表页解决办法如下: 登陆dedecms后台,找到“系统”“系统基本参数”“性能选项”,把“arclist标签调用缓存”设置成0,然后把“发布文章后马上更新网站主页 ...