Poj2688cleaningrobot
这道题让我们求一个地图上的各个点之间的最短路径说白了旅行商问题。
那么我们先用一个裸的BFS求出各个点之间的最短距离,然后我们再枚举各个点的全排列即可
这道题的细节很多,详见注释
上代码~
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int d[][];int w;int h;
char map[][];bool vis[][];
int dx[]={,-,,};int dy[]={,,-,};
int res;
struct data
{
int x;int y;int step;
}n[],now;int cnt;
inline int s(int x,int y)//强制转换点坐标为点号
{
for(int i=;i<=cnt;i++)
if(n[i].x==x&&n[i].y==y)
return i;
return ;
}
queue <data> q;
int c[];
void clear()//因为每一个点都要bfs所以搜一次清空一次
{
while(!q.empty())
{
q.pop();
}
for(int i=;i<h;i++)
for(int j=;j<w;j++)
vis[i][j]=false;
return;
}
int main()
{
while()
{
res=0x3f3f3f3f;cnt=;//多组询问的时候记得赋变量初值
scanf("%d%d",&w,&h);
if(w==&&h==)break;
for(int i=;i<h;i++)
{
scanf("%s",map[i]);
for(int j=;j<w;j++)
{
if(map[i][j]=='*')
{
n[++cnt].x=i;n[cnt].y=j;
}
else if(map[i][j]=='o')
{
n[].x=i;n[].y=j;
}
}
}
for(int i=;i<=cnt;i++)//记得清空邻接矩阵
{
for(int j=;j<=cnt;j++)
{
d[i][j]=;
}
}
for(int i=;i<=cnt;i++)//裸的bfs
{
q.push(n[i]);
//printf("STARTFROM%d\n",i);
vis[n[i].x][n[i].y]=true;
int rep=cnt;
while(!q.empty())
{
now=q.front();q.pop();
int x=now.x;int y=now.y;
//printf("nowis(%d,%d)\n",x,y);
for(int k=;k<;k++)
{
if(x+dx[k]<||x+dx[k]>=h||y+dy[k]<||y+dy[k]>=w||
vis[x+dx[k]][y+dy[k]]||map[x+dx[k]][y+dy[k]]=='x')//地图中是小写的x
continue;
if(map[x+dx[k]][y+dy[k]]=='*'||map[x+dx[k]][y+dy[k]]=='o')
{
int t=s(x+dx[k],y+dy[k]);
//printf("REACH%d,DISis%d\n",t,now.step+1);
d[i][t]=now.step+;
d[t][i]=now.step+;
rep--;
if(rep==)goto nxt;
}
vis[x+dx[k]][y+dy[k]]=true;
data p;p.x=x+dx[k];p.y=y+dy[k];p.step=now.step+;
q.push(p);
}
}
nxt:;
clear();
}
for(int i=;i<=cnt;i++)
{
c[i]=i;
//printf("node%dis(%d,%d)\n",i,n[i].x,n[i].y);
}
int rep;
/*for(int i=0;i<=cnt;i++)
{
for(int j=0;j<=cnt;j++)
{
printf("%-3d",d[i][j]);
}
printf("\n");
}*/
do
{
rep=;
for(int i=;i<cnt;i++)
{
//printf("%-2d",c[i]);
if(d[c[i]][c[i+]]==)
{
printf("-1\n");goto ed;
}
rep+=d[c[i]][c[i+]];
}
//printf("%-2d",c[cnt]);
//printf("%-5d",rep);
if(res>rep)res=rep;
//printf("\n");
}while(next_permutation(c+,c+cnt+));//枚举全排列
printf("%d\n",res);
ed:;
}
return ;//拜拜程序~
}
Poj2688cleaningrobot的更多相关文章
随机推荐
- socket keepalive理解
java socket编程中有个keepalive选项,看到这个选项经常会误解为长连接,不设置则为短连接,实则不然. socket连接建立之后,只要双方均未主动关闭连接,那这个连接就是会一直保持的,就 ...
- Spring 基础知识(二)Spring的bean初始化与生命周期,以及注入
Spring bean 初始化: 参考博文: https://www.cnblogs.com/luyanliang/p/5567164.html 1. 加载xml 文件. 扫描注解 ,形成bean定义 ...
- 1.3 SQL循环
1.while循环(1~20的和) 2.while_break_continue(1~20偶数和) 3.if选择象限 4.return:在查询中无条件退出,return后面的语句将不会被执行. 5.g ...
- vue 中生成二维码之爬坑之路
最近在做vue中项目,有个需求是在你提交信息后把后台返给你的链接生成二维码. 一共使用了两种生成二维码的方法 1.vue-qr 这个是在一进入页面直接生成二维码,具体介绍见文档:https://www ...
- ASP.NET Core2.2 多用户验证和授权
asp.net core2.2 用户验证 和授权有很详细和特贴心的介绍,我感兴趣的主要是这两篇: cookie身份验证 基于角色的授权 我的项目有两类用户: 微信公众号用户,用户名为公众号的openi ...
- 音频播放器在chrome浏览器,play报错
这个问题是谷歌浏览器的问题:https://www.oschina.net/news/96168/chrome-remove-the-autoplay-policy,可以查看这篇文章 如果你的版本没有 ...
- Keil的断点调试问题解决
keil只有在程序能正常运行时才能添加断点后在点击调试任务时,断点标记不消失
- 如何开发NPM包
创建包目录 D:\>mkdir mypackage && cd mypackage D:\mypackage>npm init --yes 进入mypackage目录,你会 ...
- 转自CSDN-详述 Java 中的别名现象
在任何编程语言中,赋值操作都是最常见的操作之一,Java 自然也不例外.赋值时,使用赋值操作符=,它的意思是:“将等号右边的值(右值),复制给左边的值(左值)”.右值可以是任何常数.变量或者表达式(只 ...
- 《转》:JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
原链接:https://my.oschina.net/feichexia/blog/196575 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 ...