搜索7--noi1804:小游戏

一、心得

二、题目

1804:小游戏

总时间限制: 
1000ms

内存限制: 
65536kB
描述
一天早上,你起床的时候想:“我编程序这么牛,为什么不能靠这个赚点小钱呢?”因此你决定编写一个小游戏。

游戏在一个分割成w * h个正方格子的矩形板上进行。如图所示,每个正方格子上可以有一张游戏卡片,当然也可以没有。

当下面的情况满足时,我们认为两个游戏卡片之间有一条路径相连:

路径只包含水平或者竖直的直线段。路径不能穿过别的游戏卡片。但是允许路径临时的离开矩形板。下面是一个例子:

这里在 (1, 3)和 (4, 4)处的游戏卡片是可以相连的。而在 (2, 3) 和 (3, 4) 处的游戏卡是不相连的,因为连接他们的每条路径都必须要穿过别的游戏卡片。

你现在要在小游戏里面判断是否存在一条满足题意的路径能连接给定的两个游戏卡片。

输入
输入包括多组数据。一个矩形板对应一组数据。每组数据包括的第一行包括两个整数w和h (1 <= w, h <= 75),分别表示矩形板的宽度和长度。下面的h行,每行包括w个字符,表示矩形板上的游戏卡片分布情况。使用‘X’表示这个地方有一个游戏卡片;使用空格表示这个地方没有游戏卡片。

之后的若干行上每行上包括4个整数x1, y1, x2, y2 (1 <= x1, x2 <= w, 1 <= y1, y2 <= h)。给出两个卡片在矩形板上的位置(注意:矩形板左上角的坐标是(1, 1))。输入保证这两个游戏卡片所处的位置是不相同的。如果一行上有4个0,表示这组测试数据的结束。

如果一行上给出w = h = 0,那么表示所有的输入结束了。

输出
对每一个矩形板,输出一行“Board #n:”,这里n是输入数据的编号。然后对每一组需要测试的游戏卡片输出一行。这一行的开头是“Pair m: ”,这里m是测试卡片的编号(对每个矩形板,编号都从1开始)。接下来,如果可以相连,找到连接这两个卡片的所有路径中包括线段数最少的路径,输出“k segments.”,这里k是找到的最优路径中包括的线段的数目;如果不能相连,输出“impossible.”。

每组数据之后输出一个空行。

样例输入
5 4
XXXXX
X X
XXX X
XXX
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
0 0
样例输出
Board #1:
Pair 1: 4 segments.
Pair 2: 3 segments.
Pair 3: impossible.
来源
翻译自Mid-Central European Regional Contest 1999的试题

三、分析

分析:
1、典型的搜索问题
2、求转弯次数+1
3、可以在方框外面走,我们我们在矩阵的基础上面包一层
4、测试数据的时候列在前面

四、代码

5分

今天先到这,后面再来管

 //1804:小游戏
/*
分析:
1、典型的搜索问题
2、求转弯次数+1
3、可以在方框外面走,我们我们在矩阵的基础上面包一层
4、测试数据的时候列在前面
*/ #include <iostream>
using namespace std;
//下右上左 分别对应0,1,2,3
int goHeight[]={,,-,};
int goWidth[]={,,,-}; char maze[][];
int startW,startH,endW,endH;
bool vis[][];
int w,h;
int step;//要求的结果,有几个线段
int minStep=0xfffffff;
int Board;//案例数
int Pair;//每个案例测试数 void printMaze(){
cout<<w<<" "<<h<<endl;
for(int i=;i<=h;i++){
for(int j=;j<=w;j++){
cout<<maze[i][j];
}
cout<<endl;
}
} void printVis(){
cout<<w<<" "<<h<<endl;
for(int i=;i<=h+;i++){
for(int j=;j<=w+;j++){
cout<<vis[i][j]<<" ";
}
cout<<endl;
}
} void printAns(int minStep){ if(minStep==0xfffffff){
cout<<"Pair "<<Pair++<<": impossible."<<endl;
}
else{
cout<<"Pair "<<Pair++<<": "<<minStep<<" segments."<<endl;
}
} /*
函数说明,
有当前的朝向 (下右上左 分别对应0,1,2,3 )
有当前的坐标 (保证DFS往下走)
有转弯次数+1 (结果) :是int,如果是0,说明无解,是大于0的数,则说明解释那个数
*/
void search(int startW,int startH,int direction,int step){
//cout<<"startW: "<<startW<<" startH:"<<startH<<" direction:"<<direction<<" step:"<<step<<endl;
//printVis();
if(startW==endW&&startH==endH){
if(step<minStep) minStep=step;
}
else{
//优化一:如果中间的step大于了minStep,说明肯定不是最优解
if(step>=minStep) return;
for(int i=;i<;i++){
int w1=startW+goWidth[i];
int h1=startH+goHeight[i];
if(!vis[h1][w1]&&w1>=&&w1<=w+&&h1>=&&h1<=h+){
vis[h1][w1]=true;
int stepBefore=step,directionBefore=direction;
if(direction!=i){
step++;
direction=i; }
search(w1,h1,direction,step);
//回溯
vis[h1][w1]=false;
step=stepBefore;
direction=directionBefore;
}
}
}
} int main(){
//freopen("in.txt","r",stdin);
Board=;
while(true){
/*
第一步:初始化
*/
//----------------------------------------------------------- cin>>w>>h;
if(w==&&h==) break;
cout<<"Board #"<<++Board<<":"<<endl;
//把矩阵的外面至为可访问的
for(int i=;i<=max(w,h);i++){
//左上交
vis[][i]=false;
vis[i][]=false;
//右下角:宁可杀错,也不放过
vis[h+][i]=false;
vis[w+][i]=false;
vis[i][h+]=false;
vis[i][w+]=false;
}
//输入maze
for(int i=;i<=h;i++){
getchar();
for(int j=;j<=w;j++){
char c=getchar();
maze[i][j]=c;
if(c=='X') vis[i][j]=true;
}
} Pair=; //print函数
//printMaze();
//printVis(); /*
第二步:搜索计算
*/
//--------------------------------------------------------
while(true){
minStep=0xfffffff;
cin>>startW>>startH>>endW>>endH;
if(startW==&&startH==&&endW==&&endH==) break;
//cout<<startW<<" "<<startH<<" "<<endW<<" "<<endH<<endl;
//初始化步数
step=;
//让目的地变的可走
vis[endH][endW]=false;
search(startW,startH,,step);//默认的朝向是自由的,这是从起点开始计算线段
printAns(minStep);
//上一个目的地变成可走后,到下一个测试的要变成卡片
vis[endH][endW]=true;
}
} return ;
}
/*
1、
输入为:5 4
cin>>m>>n;后
如果用getchar()读取,读到的是行尾的"/n";
2、
目的点是有卡片的,默认情况不能走,我们要让它可走
vis[endH][endW]=false;
3、
这里是所有解中的最优解,所以是回溯而非DFS
那就要记录所有解,找到最优解
4、
优化一:如果中间的step大于了minStep,说明肯定不是最优解
if(step>=minStep) return;
5、
上一个目的地变成可走后,到下一个测试的要变成卡片
6、
在每个起点终点测试的前面,要给minStep赋初值
*/

五、注意点

1、
输入为:5 4
cin>>m>>n;后
如果用getchar()读取,读到的是行尾的"/n";
2、
目的点是有卡片的,默认情况不能走,我们要让它可走
vis[endH][endW]=false;
3、
这里是所有解中的最优解,所以是回溯而非DFS
那就要记录所有解,找到最优解
4、
优化一:如果中间的step大于了minStep,说明肯定不是最优解
if(step>=minStep) return;
5、
上一个目的地变成可走后,到下一个测试的要变成卡片
6、
在每个起点终点测试的前面,要给minStep赋初值

搜索7--noi1804:小游戏的更多相关文章

  1. 自制Unity小游戏TankHero-2D(4)关卡+小地图图标+碰撞条件分析

    自制Unity小游戏TankHero-2D(4)关卡+小地图图标+碰撞条件分析 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm ...

  2. 两个Canvas小游戏

    或许连小游戏都算不上,可以叫做mini游戏. 没有任何框架或者稍微有点深度的东西,所以有js基础的或者要追求炫酷效果的可以直接ctrl+w了. 先贴出两个游戏的试玩地址: 是男人就走30步 是男人就忍 ...

  3. OpenJudge 2802 小游戏 / Poj 1101 The Game

    1.链接地址: http://bailian.openjudge.cn/practice/2802 http://poj.org/problem?id=1101 2.题目: 总时间限制: 1000ms ...

  4. javascrpit开发连连看记录-小游戏

        工作之余,总想做点什么有意思的东西.但是苦于不知道做什么,也就一直没有什么动作.在一个午饭后,跟@jedmeng和@墨尘聊天过程中,发现可以写一些小东西来练练手,有以下几点好处:     1. ...

  5. 【C语言探索之旅】 第一部分第八课:第一个C语言小游戏

    ​ 内容简介 1.课程大纲 2.第一部分第八课:第一个C语言小游戏 3.第一部分第九课预告: 函数 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写 ...

  6. 2048小游戏代码解析 C语言版

    2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图:  游 ...

  7. 使用Laya引擎开发微信小游戏(下)

    本文由云+社区发表 6. 动画 6.1 创建伞兵对象 在src目录下创建一个新目录role,用来存放游戏中角色. 在role里创建一个伞兵Soldier.ts对象文件. module role{ ex ...

  8. 腾讯云 Game-Tech 技术沙龙小游戏专场“空降”长沙

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云发表于云+社区专栏 小游戏作为今年快速成长的新生态,在开放进入市场之后持续成为行业热点,获得了游戏开发商的高度关注与参与.在 ...

  9. .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块

    .Net Core ORM选择之路,哪个才适合你   因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别 ...

随机推荐

  1. 如何使用模板生成 sqlite3 sql 创建语句?

    template<typename T,typename... Args> std::string createTable(T tableName,Args&&... ar ...

  2. 顽石系列:Linux基础笔试

    顽石系列:Linux基础笔试 系统操作 压缩文件 扩展名 压缩程序 *.Z compress *.zip zip *.gz gzip *.bz2 bzip2 *.xz xz *.tar tar 程序打 ...

  3. nfs共享存储

    1.下载软件包 yum install nfs-utils nfs-utils-lib -y 2.编辑/etc/exports文件: 1.创建目录:mkdir -p /home/glance2.编辑e ...

  4. Bootstrap主题库

    主题 https://startbootstrap.com/template-categories/all/ https://bootstrapmade.com/ http://www.jqueryf ...

  5. python之路(sed,函数,三元运算)

    python之路(sed,函数,三元运算) 一.sed集合 1.set无序,不重复序列 2.创建 se = {11,22,33,33,44} list() #只要是一个类加上()自动执行 list _ ...

  6. PAT 天梯赛 L1-024. 后天 【取余】

    题目链接 https://www.patest.cn/contests/gplt/L1-024 题意 给出一个数,表示星期几,输出后天是星期几 思路 取余的时候要小心点 AC代码 #include & ...

  7. 修改subline text3左侧样式

    安装PackageResourceViewer 快捷键 ⌘(command)+⇧(shift)+P 打开 Command Palette 输入 Package Control:Install 回车,等 ...

  8. Linux文件系统管理 parted分区命令

    概述 parted 命令是可以在命令行直接分区和格式化的,不过 parted 交互模式才是更加常用的命令方式. parted命令 进入交互模式命令如下: [root@localhost ~]# par ...

  9. 建议13:使用Python模块re实现解析小工具

    # -*- coding:utf-8 -*- # ''' Python re 的主要功能: re.compile(pattern[, flags]) 把正则表达式的模式和标识转化成正则表达式对象,供 ...

  10. 2.3UML建模之用例图关系

    一.UML简介 UML(统一建模语言,Unified Modeling Language)是一种定义良好.易于表达.功能强大且普遍适用的可视化建模语言.它融入了软件工程领域的新思想.新方法和新技术.它 ...