博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3956 棋盘
阅读量:6271 次
发布时间:2019-06-22

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

pjT3翻车了,怕是连pj组都不如

这道题一看上去就是用bfs的啊,用dfs还怕爆栈。

然后就手动地打了个非常暴力的bfs,只拿到了25pts。

翻了题解才知道这个东西居然还能用spfa!

总结性话语:搜索题不会做的,试着转换成图论题,用图论题的思路解决暴力模拟也许会更方便


所以我们可以类似于spfa,建立一个vis数组和dist数组。

如何记录状态?

当前行列肯定要记的,然后就要考虑那个花两块钱变色的东西。

不难发现再开一维记录当前位置的颜色即可,不需要去更改原矩阵。当原颜色与当前颜色不一样的时候就说明我使用了膜法。

有一个贪心的做法:当我下一步是一个无颜色的格子,那么最优的是直接指定为同样颜色,这样只要花两块钱,不然要花三块钱。

对于不同的颜色,注意去分别判断,用类似于spfa的方法去更新。

所以就完事了。最后输出一下std::min(dist[n][n][0], dist[n][n][1])就可以了。

代码:

#include
#include
#include
const int maxn = 105;const int dx[] = {0, 0, 1, -1};const int dy[] = {1, -1, 0, 0};struct Nodes{ int x, y, col; Nodes(int x, int y, int col):x(x), y(y), col(col){}};int G[maxn][maxn];int dist[maxn][maxn][2];bool vis[maxn][maxn][2];int n, m;int main(){ memset(dist, 0x3f, sizeof dist); memset(G, -1, sizeof G); scanf("%d%d", &n, &m); while(m--) { int x, y, z; scanf("%d%d%d", &x, &y, &z); G[x][y] = z; } std::queue
q; dist[1][1][G[1][1]] = 0; q.push(Nodes(1, 1, G[1][1])); vis[1][1][G[1][1]] = true; while(!q.empty()) { Nodes u = q.front(); q.pop(); int x = u.x, y = u.y, col = u.col, res = dist[x][y][col]; vis[x][y][col] = false; for(int i = 0; i < 4; i++) { int nx = x + dx[i], ny = y + dy[i]; if(nx >= 1 && nx <= n && ny >= 1 && ny <= n) { if(G[nx][ny] == -1) { if(G[x][y] == -1) continue; if(res + 2 < dist[nx][ny][col]) { dist[nx][ny][col] = res + 2; if(!vis[nx][ny][col]) { q.push(Nodes(nx, ny, col)); vis[nx][ny][col] = true; } } } else if(G[nx][ny] != col) { if(res + 1 < dist[nx][ny][G[nx][ny]]) { dist[nx][ny][G[nx][ny]] = res + 1; if(!vis[nx][ny][G[nx][ny]]) { q.push(Nodes(nx, ny, G[nx][ny])); vis[nx][ny][G[nx][ny]] = true; } } } else if(G[nx][ny] == col) { if(res < dist[nx][ny][G[nx][ny]]) { dist[nx][ny][G[nx][ny]] = res; if(!vis[nx][ny][G[nx][ny]]) { q.push(Nodes(nx, ny, G[nx][ny])); vis[nx][ny][G[nx][ny]] = true; } } } } } } int ans; if(G[n][n] != -1) ans = dist[n][n][G[n][n]]; else ans = std::min(dist[n][n][0], dist[n][n][1]); if(ans != 0x3f3f3f3f) printf("%d\n", ans); else printf("-1\n"); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9833329.html

你可能感兴趣的文章
python自动化开发-8
查看>>
bzoj 2127: happiness
查看>>
Python 3.5 之路 day1
查看>>
selenium使用chrome抓取自动消失弹框的方法
查看>>
实现strStr()---简单
查看>>
只有PD号的调起
查看>>
返回一个整数数组中最大子数组的和
查看>>
leetcode(二)
查看>>
利用css实现居中的方法
查看>>
Spring + Hibernate 框架
查看>>
添加浏览器的用户样式表
查看>>
LigerUI学习笔记之布局篇 layout
查看>>
LeetCode题解(二)
查看>>
Mybatis通用Mapper
查看>>
文件磁盘命令(就该这么学6章内容)
查看>>
2016-207-19 随笔
查看>>
java的double类型如何精确到一位小数?
查看>>
看看国外的javascript题目,你能全部做对吗?
查看>>
ffmpeg 如何选择具有相同AVCodecID的编解码器 (AVCodec)
查看>>
真正解决 Windows 中 Chromium “缺少 Google API 密钥” 的问题
查看>>