题目
题目描述:我们把房间按照笛卡尔坐标系进行建模之后,每个点就有了一个坐标。
假设现在房子里有些纸片需要被收集,收集完纸片你还要回归到原来的位置,你需要制定一个策略来使得自己行走的距离最短。
你只能沿着 x 轴或 y 轴方向移动,从位置 (i,j) 移动到相邻位置 (i+1,j),(i-1,j),(i,j+1) 或 (i,j-1) 距离增加 1。
输入描述:
在第一行中给出一个T,1≤T≤10, 代表测试数据的组数。
对于每组输入,在第一行中给出房间大小,第二行给出你的初始位置。
接下来给出一个正整数 n,1≤n≤10 代表纸片的个数。
接下来 n 行,每行一个坐标代表纸片的位置。
保证房间小于20×20,纸片一定位于房间内。
输出描述:
对于每组输入,在一行中输出答案。格式参见样例。
解析
这道题由于我并没有想到什么办法,我就把所有的点的情况都枚举了一遍。
- 因为数据量较小,我们这里的枚举方法就是把这些点全排列一遍。我们这里阔以用到STL的全排列函数next_permutation。
- 时间复杂度O(n!)很大很大,但nb的方法我不会啊。
next_permutation:
- 这个STL的库函数的作用就是将当前序列到其全排列的下一种情况。与之相对的还有pre_permutation(上一种情况)。
操作:
- 这里操作很简单,我们就用一个字符串来做全排列。我们先记录下起始情况就结束情况,这样start == end的时候自然而然的就出来了。
- 然后里面按顺序循环遍历计算路程。
- 最后选出最小的答案输出来就好了。
打代码咯:
- 先保存所有要保存的变量。这里我们可以将起始点作为数组的0位置(方便计算)。
- 然后就是全排列查找最小情况。
- 输出来就好了,看我代码咯~
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//代码预处理区
const int INF = 0x3f3f3f3f;
const int MAX = 17;
struct Node {
int x, y;
} paper[MAX];
//全局变量区
int main() {
IOS;
// freopen("in.txt", "r", stdin);
int T; cin >> T;
while (T--) {
int high, width; cin >> high >> width;
cin >> paper[0].x >> paper[0].y;
int n; cin >> n;
string s, e;
for (int i = 1; i <= n; i++) {
cin >> paper[i].x >> paper[i].y;
s += i + '0';
e += n - i + 1 + '0';
}
s = '0' + s; e = '0' + e;
int ans = INF;
while (s != e) {
int sum = 0;
for (int i = 1; i <= n; i++) {
int u = s[i - 1] - '0', v = s[i] - '0';
sum += abs(paper[v].x - paper[u].x) + abs(paper[v].y - paper[u].y);
}
int u = s[n] - '0', v = s[0] - '0';
sum += abs(paper[v].x - paper[u].x) + abs(paper[v].y - paper[u].y);
ans = min(ans, sum);
next_permutation(s.begin() + 1, s.end());
}
cout << "The shortest path has length " << ans << endl;
}
return 0;
}
//函数区
京公网安备 11010502036488号