Pro
https://acm.hdu.edu.cn/showproblem.php?pid=7139
Sol
思路还是比较简单的,犯了几个细节错误。
关于坐标加0.5的处理方法:对每个点维护该点的上下左右四条边的情况,从而在搜索的时候按照上一个点来的方向判断那条边点的情况,即不将在方格中心的点强行放到方格顶点,而是根据顶点所连四条边的情况判断是否可以继续搜索。
思路就是直接状压,用1表示该墙存在,0表示不存在,求保证能从起点走到终点的前提下,求0的个数的最小值。
这里犯了个错误,就是将表示状态的数从小到大枚举的时候,如果发现可以了直接就break了,其实不然。即表示状态的十进制数与0的个数之间并不具有单调关系,因此一旦满足条件不能直接break,而是循环完所有的状态后,对0的个数取最小值才为答案。
Code
//By cls1277
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define endl '\n'
//const LL maxn = ;
LL n, m, K, xs, ys, xt, yt;
struct Node {
LL a, b, c, d; // u, d, l, r;
};
struct Map {
bool u, d, l, r;
} mp[20][20];
struct Que {
LL x, y; //1u, 2d, 3l, 4r
};
bool vis[20][20];
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
#ifdef DEBUG
freopen("data.txt","r",stdin);
#endif
LL t; cin>>t;
while(t--) {
cin>>n>>m>>K;
vector<Node> e(K+1);
cin>>xs>>ys>>xt>>yt;
Fo(i,1,K) {
LL a, b, c, d; cin>>a>>b>>c>>d;
if(a>c) swap(a, c);
if(b>d) swap(b, d);
e[i] = {a, b, c, d};
}
LL len = (1<<K)-1, ans = INT_MAX;
Fo(k,0,len) {
Fo(i,0,n) Fo(j,0,m) mp[i][j] = {0, 0, 0, 0}, vis[i][j] = 0;
Fo(i,1,K) {
if(((k>>(i-1))&1)==0) continue;
if(e[i].a==e[i].c) {
Fo(j,e[i].b,e[i].d) {
if(j==e[i].b) mp[e[i].a][j].u = 1;
else if(j==e[i].d) mp[e[i].a][j].d = 1;
else mp[e[i].a][j].u = mp[e[i].a][j].d = 1;
}
} else {
Fo(j,e[i].a,e[i].c) {
if(j==e[i].a) mp[j][e[i].b].r = 1;
else if(j==e[i].c) mp[j][e[i].b].l = 1;
else mp[j][e[i].b].l = mp[j][e[i].b].r = 1;
}
}
}
queue<Que> q; q.push({xs, ys});
vis[xs][ys] = 1; bool flag = 0;
while(!q.empty()) {
Que u = q.front(); q.pop();
if(u.x==xt&&u.y==yt) {
flag = 1;
break;
}
Fo(i,0,3) {
LL tx=u.x+dx[i], ty=u.y+dy[i];
if(tx<0||ty<0||tx>=n||ty>=m||vis[tx][ty]) continue;
if(i==0&&!mp[tx][ty].r) {
vis[tx][ty] = 1;
q.push({tx, ty});
} else if(i==1&&!mp[u.x][u.y].r) {
vis[tx][ty] = 1;
q.push({tx, ty});
} else if(i==2&&!mp[tx][ty].u) {
vis[tx][ty] = 1;
q.push({tx, ty});
} else if(i==3&&!mp[u.x][u.y].u) {
vis[tx][ty] = 1;
q.push({tx, ty});
}
}
}
if(flag) ans = min(ans, K-__builtin_popcount(k));
}
cout<<ans<<endl;
}
return 0;
}