补题日记[2022杭电暑期多校1]B-Dragon slayer

Posted cls1277

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补题日记[2022杭电暑期多校1]B-Dragon slayer相关的知识,希望对你有一定的参考价值。

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;

LL count(LL x) 
    LL cnt = 0;
    while(x) 
        if(x%2==0) cnt++;
        x >>= 1;
    
    return cnt;


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;

以上是关于补题日记[2022杭电暑期多校1]B-Dragon slayer的主要内容,如果未能解决你的问题,请参考以下文章

补题日记[2022杭电暑期多校3]K-Taxi

补题日记[2022杭电暑期多校3]K-Taxi

补题日记[2022杭电暑期多校2]K-DOS Card

补题日记[2022杭电暑期多校2]K-DOS Card

补题日记[2022杭电暑期多校3]B-Boss Rush

补题日记[2022杭电暑期多校3]B-Boss Rush