收集纸片
题目描述
我们把房间按照笛卡尔坐标系进行建模之后,每个点就有了一个坐标。
假设现在房子里有些纸片需要被收集,收集完纸片你还要回归到原来的位置,你需要制定一个策略来使得自己行走的距离最短。
你只能沿着 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,纸片一定位于房间内。
输出描述:
对于每组输入,在一行中输出答案。
格式参见样例。
示例1
输入
1 10 10 1 1 4 2 3 5 5 9 4 6 5
输出
The shortest path has length 24
思路:
- 状压BFS. 将纸片标号[0, tot),然后二进制状态下表示。对应位为0,表示当前状态没有捡到对应纸片,对应为1,表示当前状态已经捡到了对应纸片.满状态当然就是每一位都为1,也就是(1 << tot) - 1啦~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int read()
{
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
//状压bfs
const int maxN = 25;
const int dir[4][2] = {
1, 0,
0, 1,
-1, 0,
0, -1
};
int n, m, tot;
int sx, sy;
int mp[maxN][maxN];
bool vis[maxN][maxN][1 << 11];
void init()
{
memset(mp, -1, sizeof(mp));
memset(vis, false, sizeof(vis));
}
bool InMap(int x, int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m;
}
struct node{
int x, y, dis, sta;
};
int bfs()
{
queue<node>q;
node s = node{sx, sy, 0, 0};
if(~mp[sx][sy]) s.sta |= mp[sx][sy];
q.push(s);
vis[sx][sy][s.sta] = true;
while(!q.empty())
{
node tp = q.front(); q.pop();
for(int i = 0; i < 4; ++ i )
{
int xx = tp.x + dir[i][0];
int yy = tp.y + dir[i][1];
node nex = node{xx, yy, tp.dis + 1, tp.sta};
if(~mp[xx][yy])
nex.sta |= (1 << mp[xx][yy]);
if(!InMap(xx, yy) || vis[xx][yy][nex.sta]) continue;
q.push(nex);
vis[xx][yy][nex.sta] = true;
if(nex.sta == (1 << tot) - 1)
return nex.dis + abs(sx - xx) + abs(sy - yy);
}
}
}
int main()
{
int TAT; TAT = read();
while(TAT -- )
{
n = read(); m = read();
sx = read(); sy = read();
init();
tot = read();
for(int i = 1; i <= tot; ++ i)
{
int x, y; x = read(); y = read();
mp[x][y] = i - 1;
}
printf("The shortest path has length %d\n", bfs());
}
return 0;
}
/*
1
5 5
1 1
4
2 3
3 4
4 5
5 3
1
2 2
1 1
1
2 2
*/