您的位置:首页 > 其它

[bzoj1054][HAOI2008]移动玩具

2017-09-22 15:23 274 查看

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB

[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

今日bzoj首次非1A就在这道题上了
看到只有4*4的棋盘就应该状压加搜索
然而调了我半天
#include<bits/stdc++.h>
using namespace std;
int dis[1<<17],s,t; char ss[10];
queue < int > q;
int main(){
for( int i = 0; i < 4; i++ ){
scanf( "%s", ss );
for( int j = 0; j < 4; j++ ) s = (s<<1) + ss[j] - '0';
}
for( int i = 0; i < 4; i++ ){
scanf( "%s", ss );
for( int j = 0; j < 4; j++ ) t = (t<<1) + ss[j] - '0';
}
memset(dis,-1,sizeof(dis));
dis[s] = 0; q.push(s);
while( !q.empty() ){
int now = q.front(); q.pop();
for( int i = 0; i < 16; i++ )
if( now & (1<<i) ){
bool f1=1,f2=1,f3=1,f4=1;
if( i >= 1  ) f1 = now&(1<<(i-1));
if( i <= 14 ) f2 = now&(1<<(i+1));
if( i >= 4  ) f3 = now&(1<<(i-4));
if( i <= 11 ) f4 = now&(1<<(i+4));
if( ( i % 4 > 0 ) && !f1 ){
int v = now-(1<<i)+(1<<(i-1));
if( dis[v] == -1 ){
dis[v] = dis[now] + 1;
q.push(v);
}
}
if( ( (i+1) % 4 != 0 ) && !f2 ){
int v = now-(1<<i)+(1<<(i+1));
if( dis[v] == -1 ){
dis[v] = dis[now] + 1;
q.push(v);
}
}
if( ( i >= 4 ) && !f3 ){
int v = now-(1<<i)+(1<<(i-4));
if( dis[v] == -1 ){
dis[v] = dis[now] + 1;
q.push(v);
}
}
if( ( i <= 11 ) && !f4 ){
int v = now-(1<<i)+(1<<(i+4));
if( dis[v] == -1 ){
dis[v] = dis[now] + 1;
q.push(v);
}
}
}
if( dis[t] != -1 ) {
printf( "%d\n", dis[t] );
return 0;
}
}
return 0;
}
总结

now&(1<<(i-1))这种东西不能放在判断句里面

空间不能底到底线,前提是不炸空间
注意模拟状态
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: