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
// 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)的更多相关文章
- TC250专场
SRM 623 DIV2 1000pt 题意:给出一个最多50*50的矩阵,每个单元可能为'.'.'P'.'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形 ...
- SRM149 - SRM150(少SRM150-DIV1-LV3)
SRM 149 DIV2 1000pt 题意: 对于n个人,第i人有pi的钱.将他们分成不超过四个组,每组统一交费x,对每个人,若他拥有的钱超过x则交费,否则不交费.问最多能使这些人交多少钱. 1&l ...
- Topcoder 好题推荐
SRM SRM147 DIV1 1000pt DP SRM148 DIV1 1100pt 递归 SRM149 DIV1 1000pt math SRM150 DIV1 500pt DP SRM469 ...
- 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)数列所有 ...
- SRM 508(2-1000pt)
DIV2 1000pt 题意:给定整数n和r,求有多少个这样的数列,a1,a2...an,使得a1 + a2 +...+an = a1|a2|a3|...|an,(按位或).输出这样数列的个数mod ...
- PIC12F508/505/509/510/506/519/526/527单片机破解芯片解密方法!
IC芯片解密PIC12F508/505/509/510/506/519/526/527单片机破解 单片机芯片解密型号: PIC12F508解密 | PIC12F505解密 | PIC12F506解密 ...
- 记第一次TopCoder, 练习SRM 583 div2 250
今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...
- SRM 513 2 1000CutTheNumbers(状态压缩)
SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as St ...
- SRM 510 2 250TheAlmostLuckyNumbersDivTwo(数位dp)
SRM 510 2 250TheAlmostLuckyNumbersDivTwo Problem Statement John and Brus believe that the digits 4 a ...
随机推荐
- Android开发常见错误类型一览表
这是我的第一个博客,我会一直添加我在Android开发中遇到的错误,用来记录我开发中踩过的那些坑 ------------------------分割线------------------------ ...
- (转)[开发笔记]-js判断用户的浏览设备是移动设备还是PC
<script type="text/javascript"> function browserRedirect() { var sUserAgent = naviga ...
- C#线程池ThreadPool.QueueUserWorkItem接收线程执行的方法返回值
最近在项目中需要用到多线程,考虑了一番,选择了ThreadPool,我的需求是要拿到线程执行方法的返回值, 但是ThreadPool.QueueUserWorkItem的回调方法默认是没有返回值的,搜 ...
- 掌握JS
1.原生的js,好比全真教的武功,一步步从基础开始(先练气再御剑),很长一段时间内和jquery有很大差距,掌握以后发现jquery只不过是另外一种武功,看一遍既会.且当学原生到一定程度之后,可以自创 ...
- TortoiseGit(乌龟git)保存用户名密码的方法(转)
转自:http://my.oschina.net/jjyuangu/blog/232798?p=1 windows下比较比较好用的git客户端有2种: 1. msysgit + TortoiseGit ...
- 在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开
在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开,使用V10版本没问题,但2015中默认使用的就是V12版本,所以需要避免使用V12版本
- 原生Ajax + Promise
有原生写的ajax + promise嫁接下 ;(function(root){ var LD = function(obj){ if( obj instanceof LD ) return obj; ...
- 安装search everything中文语言包
Everything 作为很多人的必备工具,特写这篇文章,一方面让想使用国外优秀软件的英语小白有一段过渡期,另一方面也为自己整理下资料.当然,这个可不是不学好英语的正当理由. 步骤: 1. 下载好se ...
- const 笔记
.指向const的指针例如:double a=1.01;const double * b=&a;*b=2.1; //这显然是错误的a=2.1; //这是正确的,a和*b的值都会变成2.01,有 ...
- codevs 4163 hzwer与逆序对
传送门 题目描述 Description hzwer在研究逆序对. 对于数列{a},如果有序数对(I,j)满足:i<j,a[i]>a[j],则(i,j)是一对逆序对. 给定一个数列{a}, ...