题目大意: 给你一个n × m 的图,有p种宝箱, 每个点上有一个种类为a[ i ][ j ]的宝箱,a[ i ][ j ] 的宝箱里有 a[ i ][ j ] + 1的钥匙,第一种宝箱是没有锁的,

第p类宝箱只有一个且里面由宝藏,你现在在(1 ,1)问你最少需要多少步才能拿到宝藏。 (n, m <= 300)

思路:这题真的好恶心啊。。。  我们考虑p类宝箱只能从p - 1类转移过来, 这样我们就能从第一类宝箱开始往后递推, 但是最坏的情况, p 类 和p - 1类,都有45000

个点, 那么复杂度就会很大。。。  所以我们要分类讨论, 对于 (p.size()) * (p + 1. size()) > n * m 的点我们在图上进行暴力转移,复杂度微n × m, 否则我们直接暴力

转移。。。

 #include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int>>
using namespace std; const int N=+;
const int M=1e4+;
const int inf=0x3f3f3f3f;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9 + ; vector<pair<int, pii>> vec[N * N];
int n, m, p, idx, a[N][N], S, T, f[N * N], hs[N][N], vis[N][N];
bool flag[N][N];
int dx[] = {, -, , }, dy[] = { , , , -}; int dis(pii &a, pii &b) {
return abs(a.fi - b.fi) + abs(a.se - b.se);
} bool check(int x, int y) {
if(x < || x > n) return false;
if(y < || y > m) return false;
return true;
} void bfs(int p) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
flag[i][j] = false;
vis[i][j] = inf;
}
}
queue<piii> Q;
for(auto u : vec[p]) {
Q.push(mk(f[u.fi], u.se));
vis[u.se.fi][u.se.se] = f[u.fi];
} while(!Q.empty()) {
piii u = Q.front(); Q.pop();
for(int i = ; i < ; i++) {
piii nx = mk(vis[u.se.fi][u.se.se] + , mk(u.se.fi + dx[i], u.se.se + dy[i]));
if(check(nx.se.fi, nx.se.se)) {
if(vis[nx.se.fi][nx.se.se] > nx.fi)
{
vis[nx.se.fi][nx.se.se] = nx.fi;
if(!flag[nx.se.fi][nx.se.se]) {
flag[nx.se.fi][nx.se.se] = true;
Q.push(nx);
}
}
}
}
flag[u.se.fi][u.se.se] = false;
} for(auto u : vec[p + ]) {
f[u.fi] = vis[u.se.fi][u.se.se];
}
} int main() {
memset(f, inf, sizeof(f)); scanf("%d%d%d", &n, &m, &p);
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
scanf("%d", &a[i][j]); for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
vec[a[i][j]].push_back(mk(++idx, mk(i, j)));
hs[i][j] = idx;
if(a[i][j] == p) {
S = ;
T = idx;
}
}
}
f[] = ;
vec[].push_back(mk(, mk(, )));
for(int i = ; i <= p; i++) {
if(vec[i - ].size() * vec[i].size() <= n * m) {
for(auto u : vec[i - ]) {
for(auto v : vec[i]) {
f[v.fi] = min(f[v.fi], f[u.fi] + dis(u.se, v.se));
}
}
} else {
bfs(i - );
}
}
printf("%d\n", f[T]);
return ;
}
/*
*/

Codeforces Round #355 (Div. 2) D. Vanya and Treasure的更多相关文章

  1. Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

    D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...

  2. Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块

    题目链接: http://codeforces.com/contest/677/problem/D 题意: 让你求最短的从start->...->1->...->2->. ...

  3. Codeforces Round #355 (Div. 2) C. Vanya and Label 水题

    C. Vanya and Label 题目连接: http://www.codeforces.com/contest/677/problem/C Description While walking d ...

  4. Codeforces Round #355 (Div. 2) B. Vanya and Food Processor 水题

    B. Vanya and Food Processor 题目连接: http://www.codeforces.com/contest/677/problem/B Description Vanya ...

  5. Codeforces Round #355 (Div. 2) A. Vanya and Fence 水题

    A. Vanya and Fence 题目连接: http://www.codeforces.com/contest/677/problem/A Description Vanya and his f ...

  6. Codeforces Round #355 (Div. 2)-B. Vanya and Food Processor,纯考思路~~

    B. Vanya and Food Processor time limit per test 1 second memory limit per test 256 megabytes input s ...

  7. Codeforces Round #355 (Div. 2)C - Vanya and Label

    啊啊啊啊啊啊啊,真的是智障了... 这种题目,没有必要纠结来源.只要知道它的结果的导致直接原因?反正这句话就我听的懂吧... ">>"/"&" ...

  8. Codeforces Round #355 (Div. 2) B. Vanya and Food Processor

    菜菜菜!!!这么撒比的模拟题,听厂长在一边比比比了半天,自己想一想,然后纯模拟一下,中间过程检测一下,妥妥的就可以过. 题意:有N个东西要去搞碎,每个东西有一个高度,然后有一台机器支持里面可以达到的最 ...

  9. 水题 Codeforces Round #308 (Div. 2) A. Vanya and Table

    题目传送门 /* 水题:读懂题目就能做 */ #include <cstdio> #include <iostream> #include <algorithm> ...

随机推荐

  1. Java线程总结---第一天

    线程和进程各自有什么区别和优劣: 进程是资源分配的最小单位,线程是程序执行的最小单位 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段.堆栈段和数据段,这种操 ...

  2. cf1066F Yet Another 2D Walking (贪心+dijkstra)

    易证我们走的时候只会从某一层的某端点走向另一端点.然后走向下一层的某端点.. 所以建图然后dijkstra就行了 调了一年以后发现dijkstra写错了 #include<bits/stdc++ ...

  3. 前端学习 -- Css -- 行间距

    在CSS并没有为我们提供一个直接设置行间距的方式,我们只能通过设置行高来间接的设置行间距,行高越大行间距越大.使用line-height来设置行高 .行高类似于我们上学单线本,单线本是一行一行,线与线 ...

  4. debian8.4 ibus中文输入法

    安装IBus: # apt-get install ibus ibus-sunpinyin ibus-table-wubi 导入输入法: 在Activities->Applications-&g ...

  5. 关于爬取数据保存到json文件,中文是unicode解决方式

    流程: 爬取的数据处理为列表,包含字典.里面包含中文, 经过json.dumps,保存到json文件中, 发现里面的中文显示未\ue768这样子 查阅资料发现,json.dumps 有一个参数.ens ...

  6. Java中多个异常的捕获顺序(多个catch)

    import java.io.IOException; public class ExceptionTryCatchTest { public void doSomething() throws IO ...

  7. (32位)本体学习程序(ontoEnrich)系统使用说明文档

    系统运行:文件夹system下,可执行文件ontoEnrichment --------------------------------------------------------1.简单概念学习 ...

  8. JavaScript 获取 flash 对象

    关于js获取flash对象,网上有非常多的例子,我也尝试了不少方法. 虽然都能用,但是没有我最想要的东西, 后来看了下百度的,虽然很规范,各种情况都考虑到了,但是代码量却不是不容乐观, 前前后后将近2 ...

  9. CSS规范 - 最佳实践--(来自网易)

    最佳选择器写法(模块) /* 这是某个模块 */ .m-nav{}/* 模块容器 */ .m-nav li,.m-nav a{}/* 先共性 优化组合 */ .m-nav li{}/* 后个性 语义化 ...

  10. 关于SQL注入,你应该知道的那些事

    戴上你的黑帽,现在我们来学习一些关于SQL注入真正有趣的东西.请记住,你们都好好地用这些将要看到的东西,好吗? SQL注入攻击因如下几点而是一种特别有趣的冒险: 1.因为能自动规范输入的框架出现,写出 ...