传送门: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. PHP 文件写入和读取(必看篇)

    文章提纲: 一.实现文件读取和写入的基本思路 二.使用fopen方法打开文件 三.文件读取和文件写入操作 四.使用fclose方法关闭文件 五.文件指针的移动 六.Windows和UNIX下的回车和换 ...

  2. mysql 编码和汉字存储占用字节问题的探索

    MySql 5.5 之前,UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区,BMP是从哪到哪?基本就是 0000 ~ FFFF 这一区. 从MySQL 5.5 开始,可支持4 ...

  3. Individual Project - Word_frequency

    0x00 预先准备和时间规划 1.因为要用到visual studio 2013,准备学习C#,预计一天时间能基本使用. 3.了解需求并设计基本数据结构与大致流程 20min 2.根据提议实现simp ...

  4. Week 1 工程文档

    计算器——工程文档 一.输入与格式 1.数据规模 本文档的输入基于如下的要求: (1)既然是小学生,我们假设他们不会计算超过10亿的数字. (2)既然是出考试题,那么也不会出超过10亿道题目. 也就是 ...

  5. 解决AJAX session跨域失效

    1.想实现的功能是登录时有个验证码,这个验证码后台提供,然后放在session中,前台把用户输入的验证码通过AJAX发给后台,后台把session中的验证码取出来然后比较不同,一样则通过. 问题出现在 ...

  6. 美团外卖app可行性分析

    美团外卖app可行性分析 1 引言 1.1编写目的 年轻人追求时尚,快捷,因此外卖行业拥有广阔的消费群体:团购的兴起,也促进了人们的消费欲望,人们继续一个外卖平台,来满足他们的欲望.O2o模式的日渐完 ...

  7. net license tool, EasyLicense !

    net license tool, EasyLicense ! 开源 .net license tool, EasyLicense !   介绍: 过去我常常像是否有一个帮助授权的软件,它可以非常简单 ...

  8. linux_查看磁盘与目录容量

    一.查看磁盘容量命令df(report file system disk space usage) 终端运行 $ df 输出结果 我的物理主机上的 /dev/sda5 是对应着主机硬盘的分区,字母 a ...

  9. arctan

    ArcTanWhen the ArcTan functional configuration is selected, the input vector (X_IN,Y_IN) is rotated( ...

  10. ZJOI2019 Day1游记

    退役吧垃圾 考的再烂还是要把自己捡起来 如果不想让自己的OI生涯就到这里止步的话 就给我滚去拿剩下的300分吧 浙江省前十六,学校前五,day1比别人差一百多分.如果这样还能进省队的话,我就成为传说了 ...