bzoj 1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2574  Solved: 1438
[Submit][Status][Discuss]

Description

  在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。

Input

  前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。

Output

  一个整数,所需要的最少移动次数。

Sample Input

1111
0000
1110
0010

1010
0101
1010
0101

Sample Output

4
 
 
可以发现用二进制表示状态的话最多也不会超过10^5,
所以我就直接想到bfs了,状态数<=10^5,转移代价算了算最多也就16*2=32。
虽然我觉得随便一个启发式搜索或者双向BFS都能打爆我一点优化没有的bfs,
但至少这个题BFS就够了,,,也懒的加优化了,,,(所以标签放的暴力)
/**************************************************************
    Problem: 1054
    User: JYYHH
    Language: C++
    Result: Accepted
    Time:20 ms
    Memory:1684 kb
****************************************************************/
 
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int ans[maxn],S,T;
int ci[30];
char ch;
queue<int> q;
 
inline void bfs(){
    ans[S]=1,q.push(S);
    int x,to,a,b,c;
    while(!q.empty()){
        x=q.front(),q.pop();
        if(x==T){
            printf("%d\n",ans[T]-1);
            return;
        }
         
        for(int i=0;i<16;i++){
            a=(x&ci[i])?1:0,b=(x&ci[i+1])?1:0,c=(x&ci[i+4])?1:0;
            if((i&3)!=3&&(a^b)){
                to=x^ci[i]^ci[i+1];
                if(!ans[to]) ans[to]=ans[x]+1,q.push(to);
            }
            if(i<12&&(a^c)){
                to=x^ci[i]^ci[i+4];
                if(!ans[to]) ans[to]=ans[x]+1,q.push(to);               
            }
        }
    }
}
 
int main(){
    ci[0]=1;
    for(int i=1;i<=20;i++) ci[i]=ci[i-1]<<1;
    for(int i=1;i<=16;i++){
        ch=getchar();
        while(ch!='0'&&ch!='1') ch=getchar();
        S=(S<<1)+ch-'0';
    }
    for(int i=1;i<=16;i++){
        ch=getchar();
        while(ch!='0'&&ch!='1') ch=getchar();
        T=(T<<1)+ch-'0';
    }   
    bfs();
    return 0;
}

 

 

转载于:https://www.cnblogs.com/JYYHH/p/8289911.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值