[HAOI 2005][BZOJ 1054] 移动玩具

先贴一波题面

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2288  Solved: 1270

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

这题乍一看感觉怪怪的,后来一看数据规模固定为16位,状压DP可过

我所选择的策略是BFS,从开始状态枚举可能的转移状态,更新状态并入队

袋马如下:

GitHub

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cctype>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <iostream>
  7 #include <algorithm>
  8
  9 int dp[1<<16];
 10 int origin;
 11 int goal;
 12 bool inQueue[1<<16];
 13
 14 void Initialize();
 15 void BFS(int);
 16
 17 int main(){
 18     Initialize();
 19     BFS(origin);
 20     printf("%d\n",dp[goal]);
 21     return 0;
 22 }
 23
 24 void BFS(int origin){
 25     int top,target;
 26     std::queue<int> q;
 27     q.push(origin);
 28     dp[origin]=0;
 29     while(!q.empty()){
 30         top=q.front();
 31         q.pop();
 32         for(int i=0;i<16;i++){
 33             if((top&(1<<i))==0)
 34                 continue;
 35             if(i>=4&&(top&(1<<(i-4)))==0){
 36                 target=(top^(1<<i))^(1<<(i-4));
 37                 if(dp[target]>dp[top]+1){
 38                     dp[target]=dp[top]+1;
 39                     if(!inQueue[target]){
 40                         q.push(target);
 41                         inQueue[target]=true;
 42                     }
 43                 }
 44             }
 45             if(i<=11&&(top&(1<<(i+4)))==0){
 46                 target=(top^(1<<i))^(1<<(i+4));
 47                 if(dp[target]>dp[top]+1){
 48                     dp[target]=dp[top]+1;
 49                     if(!inQueue[target]){
 50                         q.push(target);
 51                         inQueue[target]=true;
 52                     }
 53                 }
 54             }
 55             if(i%4>0&&(top&(1<<(i-1)))==0){
 56                 target=(top^(1<<i))^(1<<(i-1));
 57                 if(dp[target]>dp[top]+1){
 58                     dp[target]=dp[top]+1;
 59                     if(!inQueue[target]){
 60                         q.push(target);
 61                         inQueue[target]=true;
 62                     }
 63                 }
 64             }
 65             if(i%4<3&&(top&(1<<(i+1)))==0){
 66                 target=(top^(1<<i))^(1<<(i+1));
 67                 if(dp[target]>dp[top]+1){
 68                     dp[target]=dp[top]+1;
 69                     if(!inQueue[target]){
 70                         q.push(target);
 71                         inQueue[target]=true;
 72                     }
 73                 }
 74             }
 75         }
 76     }
 77 }
 78
 79 void Initialize(){
 80     freopen("movea.in","r",stdin);
 81     freopen("movea.out","w",stdout);
 82     int pos=15;
 83     char ch=getchar();
 84     while(pos>=0){
 85         while(!isdigit(ch))
 86             ch=getchar();
 87         origin^=(ch-‘0‘)<<pos;
 88         --pos;
 89         ch=getchar();
 90     }
 91     pos=15;
 92     while(pos>=0){
 93         while(!isdigit(ch))
 94             ch=getchar();
 95         goal^=(ch-‘0‘)<<pos;
 96         --pos;
 97         ch=getchar();
 98     }
 99     memset(dp,0x7F,sizeof(dp));
100     // printf("%X %X\n",origin,goal);
101 }

Backup

然后是图包时间

时间: 2024-12-20 11:21:41

[HAOI 2005][BZOJ 1054] 移动玩具的相关文章

BZOJ 1054 移动玩具

Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的. Input 第一行四个整数W.I.N.G.表示每一个字母能由几种两个字母所替代.接下来W行,每行两个字母,表示W可以用这两个字母替代.接下来I行,每行两个字母,表示I可以用这两个字母替代.接下来N行,

BZOJ 1054 [HAOI2008]移动玩具

直接暴力广搜即可.. [网上有大神说双向广搜速度快,然而直接暴力广搜就可以过了] 队列中的状态用二进制来存储.. 我用了一个比较sb的写法,勿喷qaq 1 #include <queue> 2 #include <cstdio> 3 4 using namespace std; 5 6 unsigned int Start, End; 7 bool M[4][4]; 8 9 const int dx[] = {+0, +0, +1, -1}; 10 const int dy[] =

BZOJ 1054题解 BFS暴力求解

BZOJ 1054题解 BFS暴力求解 1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1884  Solved: 1033[Submit][Status][Discuss] Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移 动到某人

斜率优化专题2——bzoj 1010 [HNOI2008]玩具装箱toy 题解

[原题] 1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 5434  Solved: 1969 [Submit][Status] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授

[BZOJ 1054][HAOI 2008]移动玩具(BFS+判重)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1054 真是水题,感谢HAOI送的福利样例23333 裸BFS,用string做判重,会八数码就会这题. 注意由于队列中状态数很多,一定要把队列的数组开大点!!! #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <

BZOJ 1054: [HAOI2008]移动玩具( BFS )

一开始没有注意答案为0的情况然后就WA了... 挺水的BFS.. ------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cctype> #include<iostream>

BZOJ 1054 广搜

1054: [HAOI2008]移动玩具 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移 动到某人心中的目标状态. Input 前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具.接着是一个空 行.接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上. Output 一个整数,所需要的最少移动次数.

BZOJ 1054 题解

1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1888  Solved: 1035[Submit][Status][Discuss] Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移 动到某人心中的目标状态. Input 前4行表示

BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P