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;
}

 

 
posted @ 2018-01-15 20:53  蒟蒻JHY  阅读(230)  评论(0编辑  收藏  举报