洛谷 P3956 棋盘(BFS)
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)的更多相关文章
- 2017普及组D1T3 洛谷P3956 棋盘
2017普及组D1T3 洛谷P3956 棋盘 原题 题目描述 有一个m×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在 ...
- 洛谷 P3956 棋盘 解题报告
P3956 棋盘 题目描述 有一个\(m×m\)的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能 ...
- 洛谷 P3956 棋盘
题目描述 有一个m ×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上 ...
- 洛谷 P3956 棋盘(记忆化搜索)
嗯... 题目链接:https://www.luogu.org/problem/P3956 这是一道比较好搜的题,注意一些剪枝.预处理和魔法的处理问题(回溯). AC代码: #include<c ...
- 洛谷 P3956 棋盘 题解
每日一题 day5 打卡 Analysis 深搜+剪枝+瞎jb判断 1.越界 2.这个点无色 3.当前的价值已经比答案大 三种情况要剪枝 我搜索里判断要不要施法的时候没判断上一次有没有施法,白调了0. ...
- 洛谷p3956 棋盘(NOIP2017 t3)
在noip考场上本来以为只能骗暴力分,没想到最后A了: 本蒟蒻的做法比较简(zhi)单(zhang):记忆化深搜(考场上本来是想打广搜的,但我深搜稳一点就这样打了): 具体:每个点用一个f数组记录当前 ...
- 洛谷P1436 棋盘分割
洛谷题目链接 动态规划: 我们设状态$f[i][j][o][p][k]$表示一个矩形,左上角顶点坐标为$(i,j)$,右下角顶点坐标为$(o,p)$时分割了$k$次,也就是说现在是$k+1$块 我们考 ...
- 【洛谷p3956】棋盘
日常blog(✧◡✧) 棋盘[题目链接] 算法: 然后这是2017普及组: first.关于颜色处理:让c[i][j]=color+1:这样无色=0,红色=1,黄色=2: 然后其实是记忆化,将记答案的 ...
- 洛谷 P1141【BFS】+记忆化搜索+染色
题目链接:https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字 0 与 1 组成的n×n 格迷宫.若你位于一格0上,那么你可以移动到相邻 4 ...
随机推荐
- visual studio 2013的使用和单元测试
Visual Studio 2013 是一个先进的开发解决方案,各种规模的团队通过它均可设计和创建引人注目的应用程序.Visual Studio 13在新功能包括C#和VB编译器和IDE支持完全基于. ...
- Individual Project - Word frequency program——12061154Joy
Description&Requirement: http://www.cnblogs.com/jiel/p/3978727.html 项目时间估计 理解项目要求: 1h 构建项目逻辑: 1h ...
- Scrum Meeting NO.10
Scrum Meeting No.10 1.会议内容 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 "我"回答过的问题 -- 界面 √ 2 "问题" ...
- 软件工程项目之摄影App
摄影app 开发人员:Ives & Dyh 开发功能: 摄影师注册与认证,为年轻摄影师提供成长的空间,发挥一技之长的平台. 用户注册与验证,为有摄影需求的人提供选择摄影师进行个性化拍摄的平台. ...
- Docker for windows 入门三(PowerShell命令使用)
- python贡献度分析20/80定律
#-*- coding: utf-8 -*- #菜品盈利数据 帕累托图 from __future__ import print_function import pandas as pd #初始化参数 ...
- python 协程库gevent学习--gevent源码学习(二)
在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用mon ...
- Ajax 新建对象
XMLHttpRequest对象是Ajax的基础,用于后台与服务器进行数据交互. 新的浏览器支撑XMLHttpRequest,而旧的浏览器不支持. var vari; if(window.XMLHtt ...
- Lodop调整打印项输出顺序 覆盖与层级
Lodop中的打印项,如果有输出在同一位置,或部分位置重叠的地方,打印项之间是怎么覆盖的呢?在JS里,按照Lodop语句打印项先后的执行顺序,先执行的先输出,后执行的后输出,如果有后面的打印项和前面的 ...
- string.PadLeft & string.PadRight
比如我想让他的长度是20个字符有很多字符串如string a = "123",只有3个字符怎么让他们在打印或显示在textBox上的时候不够的长度用空格补齐呢? string.Pa ...