北大poj-2688
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 4395 | Accepted: 1763 |
Description
Consider the room floor paved with square tiles whose size fits the
cleaning robot (1 * 1). There are 'clean tiles' and 'dirty tiles', and
the robot can change a 'dirty tile' to a 'clean tile' by visiting the
tile. Also there may be some obstacles (furniture) whose size fits a
tile in the room. If there is an obstacle on a tile, the robot cannot
visit it. The robot moves to an adjacent tile with one move. The tile
onto which the robot moves must be one of four tiles (i.e., east, west,
north or south) adjacent to the tile where the robot is present. The
robot may visit a tile twice or more.
Your task is to write a program which computes the minimum number of
moves for the robot to change all 'dirty tiles' to 'clean tiles', if
ever possible.
Input
input consists of multiple maps, each representing the size and
arrangement of the room. A map is given in the following format.
w h
c11 c12 c13 ... c1w
c21 c22 c23 ... c2w
...
ch1 ch2 ch3 ... chw
The integers w and h are the lengths of the two sides of the floor
of the room in terms of widths of floor tiles. w and h are less than or
equal to 20. The character cyx represents what is initially on the tile
with coordinates (x, y) as follows.
'.' : a clean tile
'*' : a dirty tile
'x' : a piece of furniture (obstacle)
'o' : the robot (initial position)
In the map the number of 'dirty tiles' does not exceed 10. There is only one 'robot'.
The end of the input is indicated by a line containing two zeros.
Output
each map, your program should output a line containing the minimum
number of moves. If the map includes 'dirty tiles' which the robot
cannot reach, your program should output -1.
Sample Input
7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0
Sample Output
8
49
-1 分析:BFS得到邻接矩阵,这样就是一个固定起点的TSP问题,再用递归DFS(也叫回溯法)+剪枝,就可以得到答案。
问题:输入数据是连续的,直到0 0终止。倒腾了好久都是WA,居然是这个原因。。。。
#include <stdio.h>
#include <stdlib.h> #define MAX_MAX 65535
#define MAX_ROOM 25
#define MAX_DIRT 15
#define Q_LEN 10000 typedef struct
{
int x;
int y;
int step;
}T_Node; const int deltax[] = {-, , , };
const int deltay[] = {, , , -}; T_Node gatDirt[MAX_DIRT];
T_Node queue[Q_LEN];
int gwLen;
int gwWide;
int gwDirtNum = ;
char gawMap[MAX_ROOM][MAX_ROOM];
int gawDist[MAX_DIRT][MAX_DIRT]; int BFS(T_Node *ptStart, T_Node *ptEnd)
{
int head = ;
int tail = ;
int direction = ;
char Map[MAX_ROOM][MAX_ROOM];
queue[head] = *ptStart; int i,j;
for(j=; j<gwLen; j++)
{
for(i=; i<gwWide; i++)
{
Map[j][i] = gawMap[j][i];
}
} Map[ptStart->y][ptStart->x] = 'x';
while(head != tail)
{
for(direction=; direction<; direction++)
{
if(queue[head].x + deltax[direction] <
|| queue[head].x + deltax[direction] >= gwWide
|| queue[head].y + deltay[direction] <
|| queue[head].y + deltay[direction] >= gwLen)
continue;
queue[tail].x = queue[head].x + deltax[direction];
queue[tail].y = queue[head].y + deltay[direction];
if(queue[tail].x == ptEnd->x && queue[tail].y == ptEnd->y)
{
return queue[head].step + ;
}
if(Map[queue[tail].y][queue[tail].x] != 'x')
{
queue[tail].step = queue[head].step + ;
Map[queue[tail].y][queue[tail].x] = 'x';
tail++;
}
}
head++;
}
return -;
} int gawIsCleaned[MAX_DIRT];
int gwBest = MAX_MAX; void DFS(int sum, int position, int deep)
{
int k = ;
int ThisSum = sum;
deep++;
if(deep == gwDirtNum)
if(sum < gwBest)
{
gwBest = sum;
return;
}
for(k=; k<gwDirtNum; k++)
{
if(gawDist[position][k] == || gawIsCleaned[k] ==)
{
continue;
}
sum += gawDist[position][k];
if(sum > gwBest)
break;
gawIsCleaned[position] = ;
DFS(sum, k, deep);
sum = ThisSum;
gawIsCleaned[position] = ;
}
return;
} int main(void)
{
int i,j;
while(scanf("%d %d", &gwWide, &gwLen))
{
getchar();
if(gwWide == || gwLen == )
{
return ;
}
gwDirtNum = ;
for(j=; j<gwLen; j++)
{
for(i=; i<gwWide; i++)
{
scanf("%c", &gawMap[j][i]);
if(gawMap[j][i] == '*')
{
gatDirt[gwDirtNum].x = i;
gatDirt[gwDirtNum].y = j;
gwDirtNum++;
}
if(gawMap[j][i] == 'o')
{
gatDirt[].x = i;
gatDirt[].y = j;
}
}
getchar();
}
for(j=; j<gwDirtNum; j++)
{
for(i=j+; i<gwDirtNum; i++)
{
gawDist[j][i] = BFS(&gatDirt[i], &gatDirt[j]);
if(gawDist[j][i] == -)
{
gwBest = ;
break;
}
if(j != ) gawDist[i][j] = gawDist[j][i];
}
} if(gwBest == )
{
gwBest = MAX_MAX;
printf("-1\n");
}
else
{
gwBest = MAX_MAX;
DFS(, , );
printf("%d\n", gwBest);
}
}
return ;
}
北大poj-2688的更多相关文章
- poj 2688 状态压缩dp解tsp
题意: 裸的tsp. 分析: 用bfs求出随意两点之间的距离后能够暴搜也能够用next_permutation水,但效率肯定不如状压dp.dp[s][u]表示从0出发訪问过s集合中的点.眼下在点u走过 ...
- 北大POJ题库使用指南
原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列 ...
- poj 2688 Cleaning Robot bfs+dfs
题目链接 首先bfs, 求出两两之间的距离, 然后dfs就可以. #include <iostream> #include <cstdio> #include <algo ...
- POJ 2688 Cleaning Robot
题意: 给你一个n*m的图.你从'o'点出发,只能走路(图中的'.')不能穿墙(图中的'x'),去捡垃圾(图中的' * ')问最少走多少步能捡完所有垃圾,如有垃圾捡不了,输出-1. 思路: 有两个思路 ...
- Cleaning Robot POJ - 2688
题目链接:https://vjudge.net/problem/POJ-2688 题意:在一个地面上,有一个扫地机器人,有一些障碍物,有一些脏的地砖,问,机器热能不能清扫所有的地砖, (机器人不能越过 ...
- 【Java】深深跪了,OJ题目Java与C运行效率对比(附带清华北大OJ内存计算的对比)
看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. -------------------------------------- 这是切割线 ----------- ...
- POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)
Network Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14021 Accepted: 5484 Specia ...
- 各大OJ
北大POJ 杭电HDU 浙大ZOj 蓝桥杯 PAT
- leetcode学习笔记--开篇
1 LeetCode是什么? LeetCode是一个在线的编程测试平台,国内也有类似的Online Judge平台.程序开发人员可以通过在线刷题,提高对于算法和数据结构的理解能力,夯实自己的编程基础. ...
- OJ题目JAVA与C运行效率对比
[JAVA]深深跪了,OJ题目JAVA与C运行效率对比(附带清华北大OJ内存计算的对比) 看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. ----------- ...
随机推荐
- 关于codeblock中一些常用的快捷键(搬运)
关于codeblock中一些常用的快捷键(搬运) codeblock作为一个常用的C/C++编译器,是我最常用的一款编译器,但也因为常用,所以有时为了更加快速的操作难免会用到一些快捷键,但是因为我本身 ...
- [Docker] Docker简介
一.简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间 ...
- ElasticSearch 5.0.1 java API操作
今天来说下使用ES 5.0.1的API来进行编码. 开始之前,简单说下5.0.1跟之前的几个变化.之前的ES自身是不支持delete-by-query的,也就是通过查询来删除,可以达到批量的效果,是因 ...
- 理解Javascript之执行上下文(Execution Context)
1>什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 - 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码 - 当执行一 ...
- JavaScript实现快速排序
思想: 通过分治思想.递归方法将数据依次分解为包含较小元素和较大元素的不同子序列 1.在数组中选择一个元素为基准 2.对数组进行遍历,小于基准的元素都移到基准的左边,大于基准的元素都移到基准的右边 3 ...
- js判断是手机还是电脑访问网站
js判断是手机还是电脑访问网站 <script type="text/javascript"> <!- ...
- 全球Top10最佳移动统计分析sdk
监视应用程序的分析帮助您优化您的移动应用程序的某些元素,它也给你正确的洞察到你的营销计划.没有手机的分析软件包会有缺乏必要的数据,以帮助你提高你的应用程序需要.如果你是一个软件开发者或出版商为Goog ...
- WeCenter二次开发教程(一):熟悉模板结构
<1>程序文件目录介绍: app – 应用目录 models – 模型目录 plugins – 插件目录 static – 静态文件 system – 系统目录 views – 模板目录 ...
- 《Linux内核设计与实现》课本第十八章自学笔记——20135203齐岳
<Linux内核设计与实现>课本第十八章自学笔记 By20135203齐岳 通过打印来调试 printk()是内核提供的格式化打印函数,除了和C库提供的printf()函数功能相同外还有一 ...
- java selenium (十四) 处理Iframe 中的元素
有时候我们定位元素的时候,发现怎么都定位不了. 这时候你需要查一查你要定位的元素是否在iframe里面 阅读目录 什么是iframe iframe 就是HTML 中,用于网页嵌套网页的. 一个网页可以 ...