BZOJ大视野 1054: [HAOI2008]移动玩具 解题报告

14 篇文章 0 订阅

宽搜,模拟0向上下左右四个方向的移动,

数据4*4 , 判重可以把矩阵转成2进制判重


code:

/**************************************************************
    Problem: 1054
    Language: C++
    Result: Accepted
    Time:2024 ms
    Memory:16116 kb
****************************************************************/
 
// Forever_LF  
#include<cstdio>  
#include<cstring>  
#include<iostream>  
using namespace std;  
     
const int dx[4]={-1,0,1, 0};
const int dy[4]={ 0,1,0,-1};
struct node
{
    int a[6][6],num;
    node(){ num = 0; }
}ed,list[100000]; int k,head,tail;
bool v[6][6];
int appear[100000],r,ans;
 
int Z( node x )
{
    int i,j,l;
    l=0;
    for( i=1;i<=4;i++ )
        for( j=1;j<=4;j++ )
            l = l *2 + x.a[i][j];
     
    return l;
}
bool pd( node x )
{
    int tmp=0,i,j;
    bool v=true;
     
    tmp = Z( x );
    if( tmp == ans )
    {
        k = x.num;
        return true;
    }
    for( i=1;i<=r;i++ )
        if( tmp == appear[i] )
        {
            v = false;
            break;
        }
    if( v ) appear[ ++r ] = tmp;
    return v;
}
void bfs(  )
{
    int i,j,l,xx,yy;
    head = tail = 1;
    while( head<=tail )
    {
        node x = list[head];
         
        for( i=1;i<=4;i++ )
            for( j=1;j<=4;j++ )
                if( x.a[i][j] == 0 )
                    for( l=0;l<4;l++ )
                    {
                        xx = i+dx[l];
                        yy = j+dy[l];
                        if( v[xx][yy] )
                        {
                            node y=x;
                            y.num++;
                            y.a[xx][yy] = x.a[i][j];
                            y.a[i][j]   = x.a[xx][yy];
                            if( pd( y ) ) list[++tail] = y;
                            if( k ) return;
                        }
                    }
         
        head++;
    }
    return;
}
 
int main()  
{
    int i,j;
    char s;
    for( i=0;i<=5;i++ )
        for( j=0;j<=5;j++ )
            v[i][j] = false;
             
    for( i=1;i<=4;i++ )
    {
        for( j=1;j<=4;j++ )
        {
            scanf("%c",&s);
            list[1].a[i][j] = s-48;
            v[i][j]=true;
        }
        getchar();
    }
    getchar();
    for( i=1;i<=4;i++ )
    {
        for( j=1;j<=4;j++ )
        {
            scanf("%c",&s);
            ed.a[i][j] = s-48;
        }
        getchar();
    }
    ans = Z( ed );
    appear[ ++r ] = Z( list[1] );
    if( ans == appear[1] ) { printf("0\n");return 0; }
     
    bfs();
    printf( "%d\n",k );
     
    return 0;  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值