• BZOJ 1054 广搜


    1054: [HAOI2008]移动玩具

      在一个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
     

    分析:

    这道题拿到之后第一件想到的事情就是,诶!这是道深搜题诶。而且这个搜索很明显。这道题的数据应该也挺水的所以,就没想什么别的方法

    我想的简单粗暴。
    1,我们发现,无论怎么移动,如果初始和最终都放了话,那个位置其实不用考虑。因为。就算要移动它,因为它本来就要放哪个位置,那就得找一个新的放在哪个位置。这个过程我们可以想成移动别的点经过了这个位置。
    2,因为如果深搜每次只能移动一个点。那么我们就在去完重后对每个初始节点将整张图搜索一遍。将每个遇到对目标节点记录其的步数。这些都放到一个forces [ number ] [ z ] 这里number指的是第几个初始节点 z指的是第几个目标节点。枚举整个图。完成整个表。。为什么我们每次不举最短的那个目标节点。因为。纵观全局,可能会遇到。虽然这个点当前是最近的。但是对别的点来说就没有最近的点。所以我们得考虑全局。当然考虑全局有很多办法。但是我都说了没想什么办法。直接暴力。
    3,之后就是组合整个forces数组了,每次每个目标节点只能与一个初始节点匹配。同时还保证综合的步数最小。因为我没这么想(同上)。既然都这么暴力了!那就更暴力一点啊啊啊啊!!!!!!直接用全排列来解决这个问题。

    这就是我的黄暴做法。然而所以。就是这样。dalao看到了千万别喷。

    #include<cstdio>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int one[5][5],two[5][5],cnt;
    int forces[17][17];
    int left[4]={1,-1,0,0},right[4]={0,0,1,-1};
    int visit[5][5],ans=214748;
    int visit_1[20];
    struct node{
        int x,y,step;
    }queue[1001];
    void BFS(int x_1,int y_1,int number)
    {
        memset(visit,0,sizeof(visit));
        int head=1,last=1;
        node first;
        first.x=x_1;first.y=y_1;first.step=0;
        queue[1]=first;visit[x_1][y_1]=1;
        while(head<=last)
        {
    	node news=queue[head];
    	for(int i=0;i<4;++i)
    	{
    	    int x=news.x+left[i],y=news.y+right[i];
    	    if(x>0&&x<=4&&y>0&&y<=4&&(!visit[x][y]))
    	    {
    		node zz;
    		zz.x=x;zz.y=y;zz.step=news.step+1;
    		if(two[x][y]){
    		    forces[number][two[x][y]]=zz.step;
    		}
    		queue[++last]=zz;
    		visit[x][y]=1;
    	    }
    	}
    	++head;
        }
        return ;
    }
    int lie[20];
    void DFS(int x)
    {
        if(x>cnt)
        {
    	int ans_1=0;
    	for(int i=1;i<=cnt;++i)
    	{
    	    ans_1+=forces[i][lie[i]];
    	}
    	ans=min(ans,ans_1);
    	return ;
        }
        for(int i=1;i<=cnt;i++)
        {
    	if(visit_1[i])continue;
    	visit_1[i]=1;
    	lie[x]=i;
    	DFS(x+1);
    	visit_1[i]=0;
    	lie[x]=0;
        }
        return ;
    }
    int main()
    {
        for(int i=1;i<=4;++i)
    	for(int j=1;j<=4;++j)
    	    scanf("%1d",&one[i][j]);
         for(int i=1;i<=4;++i)
    	for(int j=1;j<=4;++j)
    	{
    	    scanf("%1d",&two[i][j]);
    	    if(two[i][j]==1&&two[i][j]==one[i][j])
    		one[i][j]=two[i][j]=0;
    	    else if(two[i][j]==1){
    	    	++cnt;
    	    	two[i][j]=cnt;
    	    }
    	}
         int cnt_1=0;
         for(int i=1;i<=4;i++)
    	 for(int j=1;j<==4;++j)
    	 {
    	     if(one[i][j])
    	     {
    		 ++cnt_1;
    		 BFS(i,j,cnt_1);
    	     }
    	 }
         DFS(1);
         printf("%d",ans);
         return 0;
    }
    

    嗯。就是这样。我觉得已经够暴力了。。

  • 相关阅读:
    String和byte互转,Base64正逆向
    Http请求体详解
    ubuntuserver升级内核
    ElementUI Checkbox 多选框
    kubeadm1.20.0+cilium+hubble环境搭建
    ubuntu安装Kubernetes1.20.0
    使用mysql8.0
    用python 分析一段波浪的浪顶和浪底
    TOM 什么是目标运营模式
    Qt Quick 配置android开发环境
  • 原文地址:https://www.cnblogs.com/uncle-lu/p/5958517.html
Copyright © 2020-2023  润新知