传送门:Problem P3956

https://www.cnblogs.com/violet-acmer/p/9827010.html

题解:

  BFS

  相关变量解释:

    color[maxn][maxn];...................................color[ i ][ j ] : ( i , j )点的颜色,-1代表无色
    dp[maxn][maxn];.......................................dp[ i ][ j ] : 从( 1 , 1 )点到( i , j )点需要花费的最少金币
    magic[maxn][maxn];..................................magic[ i ][ j ] : 判断 ( i , j )点是否使用魔法
    in[maxn][maxn];.........................................in[ i ][ j ] : 判断( i , j )点是否在队列中

  具体步骤:

    初始,将(1,1)点加入队列中;

    (1):保存队头元素并弹出

    (2):每次,判断当前点的上下左右点是否可以通过当前点使dp[ ][ ]变小,如果可以,更新dp[ ][ ],如果被更新的点不在队列中,加入队列

    (3):重复(2)过程,直到队列为空

AC代码:

 #include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define P pair<int ,int >
#define mem(a,b) memset(a,b,sizeof a)
const int maxn=+; int m,n;
int color[maxn][maxn];
int dp[maxn][maxn];
bool marge[maxn][maxn];
bool in[maxn][maxn];
queue<P >myqueue;
int dx[]={-,,,};
int dy[]={,,-,};
bool isSat(int val)
{
return val >= &&val <= m;
}
void Solve()
{
dp[][]=;//初始化dp[1][1],并将其加入到队列中
myqueue.push(P(,));
while(!myqueue.empty())//步骤(3)
{
P p=myqueue.front();//步骤(1)
myqueue.pop();
in[p.first][p.second]=false;
for(int i=;i < ;++i)//步骤(2)
{
int x=p.first+dx[i];
int y=p.second+dy[i];
if(isSat(x) && isSat(y))
{
if(!marge[p.first][p.second])//如果当前点的未使用过魔法的,也就意味这当前点的颜色是本身就有的
{
if(!marge[x][y])//如果与当前点相邻的点(x,y)也为曾使用过魔法
{
if(color[x][y] != -)//如果点(x,y)有色,但并不是因为魔法而产生的
{
//如果当前点可以放缩dp[x][y]
if(dp[x][y] > dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]))
{
dp[x][y]=dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]);
if(!in[x][y])//被放缩的点(x,y)如果不在队列中,加入队列
in[x][y]=true,myqueue.push(P(x,y));
}
}
else//如果无色,通过使用魔法将其变为与当前点颜色相同的点,并被放缩了dp[][]
{
marge[x][y]=true;
color[x][y]=color[p.first][p.second];
dp[x][y]=dp[p.first][p.second]+;
if(!in[x][y])
in[x][y]=true,myqueue.push(P(x,y));
}
}
else if(dp[x][y] > dp[p.first][p.second]+)//如果点(x,y)在之前使用过魔法,就需要判断,当前为使用过魔法的点是否可以放缩dp[x][y]
{
dp[x][y]=dp[p.first][p.second]+;
color[x][y]=color[p.first][p.second];
if(!in[x][y])
in[x][y]=true,myqueue.push(P(x,y));
}
}
else if(!marge[x][y] && color[x][y] != -)//如果当前点的使用过魔法的,也就意味这当前点的颜色是通过魔法变来的,那么,只有当其临近点(x,y)含有的颜色是其本身就有的才有资格判断是否可以被放缩
{
if(dp[x][y] > dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]))
{
dp[x][y]=dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]);
if(!in[x][y])
myqueue.push(P(x,y)),in[x][y]=true;
}
}
}
}
}
printf("%d\n",dp[m][m] == INF ? -:dp[m][m]);
}
void Init()
{
mem(dp,INF);
mem(in,false);
mem(marge,false);
mem(color,-);
}
int main()
{
scanf("%d%d",&m,&n);
Init();
for(int i=;i <= n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
scanf("%d",&color[x][y]);
}
Solve();
}

  

洛谷 P3956 棋盘(BFS)的更多相关文章

  1. 2017普及组D1T3 洛谷P3956 棋盘

    2017普及组D1T3 洛谷P3956 棋盘 原题 题目描述 有一个m×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在 ...

  2. 洛谷 P3956 棋盘 解题报告

    P3956 棋盘 题目描述 有一个\(m×m\)的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能 ...

  3. 洛谷 P3956 棋盘

    题目描述 有一个m ×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上 ...

  4. 洛谷 P3956 棋盘(记忆化搜索)

    嗯... 题目链接:https://www.luogu.org/problem/P3956 这是一道比较好搜的题,注意一些剪枝.预处理和魔法的处理问题(回溯). AC代码: #include<c ...

  5. 洛谷 P3956 棋盘 题解

    每日一题 day5 打卡 Analysis 深搜+剪枝+瞎jb判断 1.越界 2.这个点无色 3.当前的价值已经比答案大 三种情况要剪枝 我搜索里判断要不要施法的时候没判断上一次有没有施法,白调了0. ...

  6. 洛谷p3956 棋盘(NOIP2017 t3)

    在noip考场上本来以为只能骗暴力分,没想到最后A了: 本蒟蒻的做法比较简(zhi)单(zhang):记忆化深搜(考场上本来是想打广搜的,但我深搜稳一点就这样打了): 具体:每个点用一个f数组记录当前 ...

  7. 洛谷P1436 棋盘分割

    洛谷题目链接 动态规划: 我们设状态$f[i][j][o][p][k]$表示一个矩形,左上角顶点坐标为$(i,j)$,右下角顶点坐标为$(o,p)$时分割了$k$次,也就是说现在是$k+1$块 我们考 ...

  8. 【洛谷p3956】棋盘

    日常blog(✧◡✧) 棋盘[题目链接] 算法: 然后这是2017普及组: first.关于颜色处理:让c[i][j]=color+1:这样无色=0,红色=1,黄色=2: 然后其实是记忆化,将记答案的 ...

  9. 洛谷 P1141【BFS】+记忆化搜索+染色

    题目链接:https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字 0 与 1 组成的n×n 格迷宫.若你位于一格0上,那么你可以移动到相邻 4 ...

随机推荐

  1. Linux下rsyslog日志收集服务环境部署记录

    rsyslog 可以理解为多线程增强版的syslog. 在syslog的基础上扩展了很多其他功能,如数据库支持(MySQL.PostgreSQL.Oracle等).日志内容筛选.定义日志格式模板等.目 ...

  2. 对于windows 10使用感受

    windows 10是美国微软公司研发的新一代跨平台及设备应用的操作系统.在2015年7月29日12点起,windows 10推送全面开始,windows 7.windows 8 用户可以升级到win ...

  3. QT QProgressBar QProgressDialog 模态,位置设置,无边框,进度条样式

    一  关于模态设置 QProgressDialog可以设置模态(需要在new的时候传入parent),QProgressBar设置不好: 只有dialog可以设置模态,widget不能设置模态(QPr ...

  4. 第五届蓝桥杯C++B组 地宫取宝

    代码: #include <bits/stdc++.h> using namespace std; #define ll long long const ll mod = 1e9 + 7; ...

  5. DELPHI XE10,JSON 生成和解析,再利用INDYHTTP控件POST

    Delphi XE10,Json 生成和解析,再利用indyhttp控件Post 年09月20日 :: 阅读数: --不多说,直接上代码 procedure TFrmMain.Brand; var J ...

  6. []转帖] 浅谈Linux下的五种I/O模型

    浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html  一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是 ...

  7. 周刷题第二期总结(Longest Substring Without Repeating Characters and Median of Two Sorted Arrays)

    这周前面刷题倒是蛮开心,后面出了很多别的事情和问题就去忙其他的,结果又只完成了最低目标. Lonest Substring Without Repeating Characters: Given a ...

  8. Mac 电脑 开发环境Idea环境搭建

    1.应该把F1-->F9的快捷键禁用,不然调试的时候,需要走断点. ==>用手抓一下键盘==>到了桌面,然后==>点击系统偏好设置==>键盘==>键盘==>将 ...

  9. sql server2005查询分析器显示行号方法

    工具栏:工具--选项--文本编辑器---所有语言--右边复选框 行号 打上勾就ok了

  10. face detection,landmark, recognition with deeplearning

    人脸特征点定位 Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Neural Networks c ...