zoukankan      html  css  js  c++  java
  • 【位运算】【BFS】移动玩具

    1054: [HAOI2008]移动玩具

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2246  Solved: 1246
    [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

    HINT

     

    Source

    试题分析:也许太闲的了,我竟然使位运算写这题(一时脑抽)……

                   简简单单的BFS,正解再加个HASH搞定

                   想想我这样好像还省了个Hash QAQ

    代码(大神勿喷)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<algorithm>
    //#include<cmath>
    
    using namespace std;
    const int INF = 9999999;
    #define LL long long
    
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    int N,E;
    bool vis[65539];
    char c;
    int l=1,r=1;
    struct data{
    	int st,k;
    }Que[700001];
    
    void BFS(){
    	Que[l].st=0,Que[l].k=N;
    	int step,Now;
    	if(Que[l].k==E){
    		printf("%d
    ",Que[l].st);
    		return ;
    	}
    	while(l<=r){
    		Now=Que[l].k,step=Que[l].st;
    		for(int i=1;i<=4;i++){
    			for(int j=1;j<=4;j++){
    				if(((Now>>((4-i)*4+4-j))&1)){
    					for(int p=0;p<4;p++){
    						if(p==0&&i!=1&&!((Now>>((4-(i-1))*4+4-j))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+8-j))]){
    							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+8-j));
    							if(Que[r].k==E){
    								printf("%d
    ",step+1);
    								return ;
    							}
    							Que[r].st=step+1;
    							vis[Que[r].k]=1;
    						}
    						if(p==1&&i!=4&&!((Now>>((4-(i+1))*4+4-j))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4-j))]){
    							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4-j));
    							if(Que[r].k==E){
    								printf("%d
    ",step+1);
    								return ;
    							}
    							Que[r].st=step+1;
    							vis[Que[r].k]=1;
    						}
    						if(p==2&&j!=1&&!((Now>>((4-i)*4+4-(j-1)))&1)&&!vis[(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j-1)))]){
    							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j-1)));
    							if(Que[r].k==E){
    								printf("%d
    ",step+1);
    								return ;
    							}
    							Que[r].st=step+1;
    							vis[Que[r].k]=1;
    						}
    						if(p==3&&j!=4&&!((Now>>((4-i)*4+4-(j+1)))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j+1)))]){
    							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j+1)));
    							if(Que[r].k==E){
    								printf("%d
    ",step+1);
    								return ;
    							}
    							Que[r].st=step+1;
    							vis[Que[r].k]=1;
    						}
    					}
    				}
    			}
    		}
    		
    		l++;
    	}
    }
    
    int main(){
    	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	int tmp=16;
    	for(int i=1;i<=4;i++)
    	    for(int j=1;j<=4;j++){
    	    	cin>>c;
    	    	N=N+(1<<(tmp-1))*(c-'0');
    	    	tmp--;
    		}
    	vis[N]=true;
    	tmp=16;
    	for(int i=1;i<=4;i++)
    	    for(int j=1;j<=4;j++){
    	    	cin>>c;
    	    	E=E+(1<<(tmp-1))*(c-'0');
    	    	tmp--;
    		}
    	BFS();
    	return 0;
    }
    

      

  • 相关阅读:
    nepenthes用法
    honeydctl命令
    honeyd路由拓扑
    Linux Samba服务器的安装
    honeyd使用
    FreeRTOS 事件标志组
    epoll函数
    Java程序:从命令行接收多个数字,求和并输出结果
    《大道至简》第一章读后感
    【诗词歌赋】 杂感- 贺小妹
  • 原文地址:https://www.cnblogs.com/wxjor/p/6964278.html
Copyright © 2011-2022 走看看