题目描述

有一个m \times mm×m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、 下、左、 右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 11个金币。

另外, 你可以花费 22 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?

输入输出格式

输入格式:

第一行包含两个正整数m, nm,n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的nn行,每行三个正整数x, y, cx,y,c, 分别表示坐标为(x,y)(x,y)的格子有颜色cc。

其中c=1c=1 代表黄色,c=0c=0 代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标为(1, 1)(1,1),右下角的坐标为( m, m)(m,m)。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1, 1)(1,1) 一定是有颜色的。

输出格式:

一个整数,表示花费的金币的最小值,如果无法到达,输出-1−1。

输入输出样例

输入样例#1:

5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
输出样例#1:

8
输入样例#2:

5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
输出样例#2:

-1

说明

输入输出样例 1 说明

从(1,1)(1,1)开始,走到(1,2)(1,2)不花费金币

从(1,2)(1,2)向下走到(2,2)(2,2)花费 11 枚金币

从(2,2)(2,2)施展魔法,将(2,3)(2,3)变为黄色,花费 22 枚金币

从(2,2)(2,2)走到(2,3)(2,3)不花费金币

从(2,3)(2,3)走到(3,3)(3,3)不花费金币

从(3,3)(3,3)走到(3,4)(3,4)花费 11 枚金币

从(3,4)(3,4)走到(4,4)(4,4)花费 11 枚金币

从(4,4)(4,4)施展魔法,将(4,5)(4,5)变为黄色,花费22 枚金币,

从(4,4)(4,4)走到(4,5)(4,5)不花费金币

从(4,5)(4,5)走到(5,5)(5,5)花费 11 枚金币

共花费 88枚金币。

输入输出样例 2 说明

从( 1, 1)(1,1)走到( 1, 2)(1,2),不花费金币

从( 1, 2)(1,2)走到( 2, 2)(2,2),花费11金币

施展魔法将( 2, 3)(2,3)变为黄色,并从( 2, 2)(2,2)走到( 2, 3)(2,3)花费22 金币

从( 2, 3)(2,3)走到( 3, 3)(3,3)不花费金币

从( 3, 3)(3,3)只能施展魔法到达( 3, 2),( 2, 3),( 3, 4),( 4, 3)(3,2),(2,3),(3,4),(4,3)

而从以上四点均无法到达( 5, 5)(5,5),故无法到达终点,输出-1−1

数据规模与约定

对于 330%的数据, 1 ≤ m ≤ 5, 1 ≤ n ≤ 101≤m≤5,1≤n≤10。

对于 60%的数据, 1 ≤ m ≤ 20, 1 ≤ n ≤ 2001≤m≤20,1≤n≤200。

对于 100%的数据, 1 ≤ m ≤ 100, 1 ≤ n ≤ 1,0001≤m≤100,1≤n≤1,000。

解析:

看到这个程序我首先想到的就是深度优先搜索,这样只能过部分数据,其他超时(TLE)。

#include<iostream>
using namespace std;
int chess[][]={};
int flag[][]={};
int dx[]={-,,,};
int dy[]={,,-,};
int m,n,total=;
int dgp(int x,int y,int color,int sum){
if(x==m&&y==m&&sum<total){total=sum; return ;}
for(int i=;i<=;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!flag[xx][yy]&&chess[xx][yy]!=-&&(chess[x][y]!=||chess[xx][yy]!=)){
flag[xx][yy]=;
if(chess[xx][yy]==chess[x][y]||(chess[x][y]==&&color==chess[xx][yy]))dgp(xx,yy,chess[x][y],sum);
else if(chess[xx][yy]==)dgp(xx,yy,chess[x][y],sum+);
else dgp(xx,yy,chess[x][y],sum+);
flag[xx][yy]=;
} }
}
int main(){
int x,y,c;
cin>>m>>n;
for(int i=;i<=m+;i++) chess[i][]=chess[][i]=chess[m+][i]=chess[i][m+]=-;
for(int i=;i<=m;i++)
for(int j=;j<=m;j++)
chess[i][j]=;
for(int i=;i<=n;i++){
cin>>x>>y>>c;
chess[x][y]=c+;
}
flag[][]=;
dgp(,,,);
if (total==) cout <<-;
else cout<<total;
return ;
}

于是我添加了2个剪枝,竟然全部Ac,由此得出结论“暴力出奇迹,剪枝少不了!!!”

#include<iostream>
using namespace std;
int chess[][]={};// 棋盘
int flag[][]={};//访问标记
int dist[][]={}; //记录最短距离
int dx[]={-,,,};
int dy[]={,,-,};
int inf=;
int m,n,total=inf; int dfs(int x,int y,int color,int sum){//记忆化搜索
if (sum>=dist[m][m]) return ;//剪枝1,如果到达当前点的距离已经大于等于终点
if (dist[x][y]<=sum) return ;//剪枝2,如果到达当前点的距离不是当前最优。
dist[x][y]=sum;//如果到达当前点的距离是当前最优
if(x==m&&y==m&&sum<dist[m][m]){dist[m][m]=sum; return ;}//如果到达终点
for(int i=;i<=;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!flag[xx][yy]&&chess[xx][yy]!=-&&(chess[x][y]!=||chess[xx][yy]!=)){
flag[xx][yy]=;//已经访问标记
if(chess[xx][yy]==chess[x][y]||(chess[x][y]==&&color==chess[xx][yy])){dfs(xx,yy,chess[x][y],sum);}
else if(chess[xx][yy]==){dfs(xx,yy,chess[x][y],sum+);}
else {dfs(xx,yy,chess[x][y],sum+);}
flag[xx][yy]=;//撤销访问标记,回溯。
} }
}
int main(){
int x,y,c;
cin>>m>>n;
for(int i=;i<=m+;i++) chess[i][]=chess[][i]=chess[m+][i]=chess[i][m+]=-;//边界
for(int i=;i<=m;i++)
for(int j=;j<=m;j++)
{chess[i][j]=;dist[i][j]=inf;}
for(int i=;i<=n;i++){
cin>>x>>y>>c;
chess[x][y]=c+;
}
flag[][]=;//起点
dfs(,,,);
if (dist[m][m]==inf) cout <<-;
else cout<<dist[m][m];
return ;
}

棋盘(noip2017普及组)的更多相关文章

  1. P3956 [NOIP2017 普及组] 棋盘

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

  2. [NOIP2017普及组]跳房子(二分,单调队列优化dp)

    [NOIP2017普及组]跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 nn 个格子, ...

  3. 「LOJ 6373」NOIP2017 普及组题目大融合

    NOIP2017 普及组题目大融合 每个读者需要有某个后缀的书,可以暴力map,复杂度\(o(9*nlog(n))\),也可以反串建trie树,复杂度\(o(9*n)\). 故可以求出需要的最少的RM ...

  4. noip2017普及组

    过了这么久才来写博客,也是我这么一段时间都很低迷吧.... 老实来说,今年应该是要打提高组的...可还是打了普及组... 其实最猥琐的还是我连普及都写挂了,作为一个学了两年的人,图论,进阶dp都写过的 ...

  5. NOIP2017普及组比赛总结

    期中考总结&NOIP2017总结 2017年11月11日,我第二次参加NOIP普及组复赛.上一年,我的得分是250分,只拿到了二等奖.我便把目标定为拿到一等奖,考到300分以上. 早上8点多, ...

  6. NOIP2017普及组解题报告

    刚参加完NOIP2017普及,只考了210,于是心生不爽,写下了这篇解题报告...(逃 第一次写博,望dalao们多多指导啊(膜 第一题score,学完helloworld的人也应该都会吧,之前好多人 ...

  7. NOIP2017普及组初赛试题及答案

    普及组C++语言试题 一.单项选择题(共 20 题,每题 1.5 分,共计 30 分:每题有且仅有一个正确选项) 1.在 8 位二进制补码中,10101011 表示的数是十进制下的( ). A. 43 ...

  8. NOIP2017普及组T2题解

    还是神奇的链接 上面依然是题目. 这道题依然很简单,比起2015年的普及组t2好像还是更水一些. 不过这道题能讲的比第一题多. 我们一起来看一下吧! 这一题,我们首先将书的编号全部读入,存在一个数组里 ...

  9. NOIP2017普及组初赛总结

    去年,我普及组复赛翻车,居然没进一等奖,于是,今年,我只能再做一次普及组. 这次初赛我93.5分,居然是中山市第一--(中山市太弱了?) 其实我觉得我没考好. 比赛时第二题(计算机存储数据的基本单位是 ...

  10. [NOIP2017普及组]棋盘

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

随机推荐

  1. [原][译]我们为什么需要另一个c++测试框架?Catch||Why do we need yet another C++ test framework?

    翻译问题来源:https://github.com/catchorg/Catch2/blob/master/docs/why-catch.md 其他辅助博文:从Google Test 转到 Catch ...

  2. java枚举通俗实例解析

    1         枚举 1.1            枚举的作用 我们经常要定义一些常量值,例如日期(MONDAY,TUESDAY……)或者错误码等.可以将常量组织起来,统一进行管理.常量比较只是值 ...

  3. MySQL 存储过程的变量

    MySQL  存储过程的变量 变量是一个命名数据对象,变量的值可以在存储过程执行期间更改.我们通常使用存储过程中的变量来保存直接/间接结果. 这些变量是存储过程的本地变量. 注意:变量必须先声明后,才 ...

  4. 配置Spring MVC - 2019

    未完 软件环境:Eclipse-EE 1. 创建Maven Project 2. pom.xml - [更新日期19/03/31] <dependencies> <dependenc ...

  5. img标签和 background 属性的使用分析

    在网页布局中引入图片,最常用的两个就是 img 标签和 background 属性了.但何时使用 img 标签,何时使用 backround 背景图像呢? <img> 标签定义 HTML ...

  6. Android 开发第一项目——计算器的开发记录

    2017.4.1 今天布局界面基本完成,现在写了一点事件绑定.计划是多用动态绑定,随时用随时改.关于布局方面,昨天弄到很晚,原因是Layout使用错误,用的自带的,没仔细看,预览的时候没有问题但是真机 ...

  7. ApiCloud开发的注意事项

    1. 引擎或模块问题:遇到应用层无法解决的问题,如果能确定需要引擎和模块支持的,不要自己想办法绕过去,要第一时间在开发者社区提交问题,或找APICloud项目经理提出. !!!注意!!!: 在开发者社 ...

  8. hdu6415 记忆化搜索或找规律

    Rikka with Nash Equilibrium Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Sub ...

  9. Maskrcnn遇到的坑

    第一个要讲maskrcnn 中keras 升到2.1 然后 在线程问题上要把workers设置成1,是否使用线程设置成false 然后调用模型的时候要把模型和加载文件放到一个目录下

  10. Win10系列:C#应用控件进阶7

    PathGeometry 前面介绍了Path的使用方法,接下来介绍PathGeometry类.PathGeometry提供了描绘由弧线.曲线和直线组成的多个复杂图形的方法.PathGeometry的核 ...