发布题解

ZZQ  •  2年前


更好的阅读体验?

【题目】

生活在一个 row * col 的矩阵(均不超过 20)的机器人每天要到n个目标点巡视,机器人起始位置坐标为(xy),机器人只能沿 xy 轴移动,不能走对角线,问从起始位置出发,走过每个目标点之后返回到起始位置,最短的路径是多少?

【输入格式】

第一行为一个整数,表示测试数据的组数。 以后每组数据的第一行为两个整数,表示矩阵大小。 第二行为两个整数,即起始位置坐标。 第三行为一个整数即目标点数 nn \le 10),随后 n 行为各点坐标,均为整数。

【输出格式】

输出最短路径,每组测试数据一行。

【输入样例】

1
10 10
1 1
4
2 3
5 5
9 4
6 5

【输出样例】

The shortest path has length 24

【算法分析】

这道题的算法最容易想到的是贪心,这是什么意思呢?就是我们寻找最近的巡视的点,统计就好了。 但我们可以发现:它走完全程后是要回到去一开始的起始位置的,所以贪心法是不可行的,举个例子:(0 表示不用走,1 表示要走,2 是起点)

2 1 1 0 1
0 0 0 0 1
0 0 0 1 0
0 0 0 0 0
0 0 0 0 1

如果我们用贪心法解决,走完(2,5)后,我们会先走(3,4),但是正确解法是走(5,5)。

出于数据不大,我们可以用搜索,试遍所有的点。

【参考代码】

int Calc(int ans = 0) {  //计算距离
  for(int i = 0; i < n; i++)
    ans += abs(p[a[i]].x-p[a[i + 1]].x) + abs(p[a[i]].y - p[a[i + 1]].y);
  ans += abs(p[a[n]].x - p[a[0]].x) + abs(p[a[n]].y - p[a[0]].y);
  return ans;
}

void DFS(int k) {  //深搜
  if(k > n)
    Min=min(Min,Calc());  //计算
  else
    for(int i = 1; i <= n; i++)
      if(used[i] == 0) {
        used[i] = 1;  //改值
        a[k] = i;
        DFS(k + 1);  //回溯
        used[i] = 0;
      }
}

评论:

顶一下


ZZQ  •  2年前