• 【BZOJ】1054: [HAOI2008]移动玩具(bfs+hash)


    http://www.lydsy.com/JudgeOnline/problem.php?id=1054

    一开始我还以为要双向广搜。。。。但是很水的数据,不需要了。

    直接bfs+hash判重即可。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int N=1000000, fx[]={-1, 1, 0, 0}, fy[]={0, 0, -1, 1};
    inline const bool check(const int &x, const int &y) { if(x<0 || x>3 || y<0 || y>3) return 0; return 1; }
    struct Matrix {
    	bool m[4][4];
    	int d;
    }q[N], ini;
    int front, tail, ans, vis[100000];
    inline int hash(const Matrix &x) {
    	int k=1, ret=0;
    	rep(i, 4) rep(j, 4) { ret+=k*x.m[i][j]; k<<=1; }
    	return ret;
    }
    
    int main() {
    	char c[10];
    	tail=1;
    	rep(i, 4) {
    		scanf("%s", c);
    		rep(j, 4)
    			q[0].m[i][j]=c[j]-'0';
    	}
    	rep(i, 4) {
    		scanf("%s", c);
    		rep(j, 4)
    			ini.m[i][j]=c[j]-'0';
    	}
    	int hs;
    	ans=hash(ini);
    	hs=hash(q[0]);
    	if(ans==hs) { printf("0"); return 0; }
    	vis[hs]=1;
    	while(front!=tail) {
    		Matrix &x=q[front++]; if(front==N) front=0;
    		rep(i, 4) rep(j, 4) if(x.m[i][j]) {
    			rep(k, 4) {
    				int px=fx[k]+i, py=fy[k]+j;
    				if(check(px, py) && x.m[px][py]==0) {
    					q[tail]=x; ++q[tail].d;
    					swap(q[tail].m[i][j], q[tail].m[px][py]);
    					hs=hash(q[tail]);
    					if(hs==ans) {
    						printf("%d", q[tail].d);
    						return 0;
    					}
    					if(vis[hs]) continue;
    					vis[hs]=1;
    					++tail; if(tail==N) tail=0;
    				}
    			}
    		}
    	}
    	return 0;
    }
    

    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

  • 相关阅读:
    jenkins master-slave配置
    ansible-playbook 变量(vars)
    ansible-playbook && Roles && include
    ansible 循环与条件判断when
    python 微信爬虫实例
    JavaScript: 零基础轻松学闭包
    【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)
    【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(一)
    【大结局】《从案例中学习JavaScript》之酷炫音乐播放器(四)
    Java 实现批量重命名,亲测可用(精简版)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3939057.html
Copyright © 2020-2023  润新知