题意: 给一个4X6的矩形,有white ,blank , grey 三种颜色各有8个格子 ,给定一个初始状态,求用最少的操作次数将图形变化为中间的8个格子颜色相同。
分析:话说,因为做过了hdu1667,一开始真的以为IDA*稳过的,敲完之后,直接TLE了,实在不解啊,原来是有测试数据的量太大了。
按照大牛的思路是这样的:当我们确定了要将中间转成什么颜色之后,转的时候发现,另外俩种颜色也就没必要区分了,所以也就可以看成是只有俩种颜色了,之后用24个位保存状态,用BFS预处理从最终状态到每一个状态需要的最小步数。最后再根据所给的图,判断将哪种颜色转到中间的步数最少即可。
虽然知道是这样的思路之后,还是一直TLE了,原来下面这俩种状态转换模式速度差那么多,ORZ
inline unsigned int changetostate()
{
unsigned int t=0;
for(int i=0;i<4;i++)
for(int j=0;j<6;j++)
{
t<<=1;
t+=(map[i][j]-'0');
}
return t;
}
inline void changetomap(unsigned int t)
{
for(int i=3;i>=0;i--)
for(int j=5;j>=0;j--)
{
map[i][j]= (t&1)+'0';
t>>=1;
}
}
下面这种比较慢,改成那么那种就过了,1200+ms
inline unsigned int changetostate()
{
unsigned int t=0;
int i,j;
for(int k=0;k<24;k++)
{
i=k/6;j=k%6;
if(map[i][j]=='1')
t|=(1<<k);
}
return t;
}
inline void changetomap(unsigned int t)
{
int i,j;
for(int k=0;k<24;k++)
{
i=k/6;j=k%6;
if(t&(1<<k))
map[i][j]='1';
else map[i][j]='0';
}
}
看整个代码吧:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
char step[1<<24];
char map[5][7];
char hash1[3]={'B','G','W'};
void init()
{
for(int i=0;i<4;i++)
for(int j=0;j<6;j++)
map[i][j]='0';
for(int i=1;i<3;i++)
for(int j=1;j<5;j++)
map[i][j]='1';
memset(step,-1,sizeof(step));
}
inline unsigned int changetostate()
{
unsigned int t=0;
for(int i=0;i<4;i++)
for(int j=0;j<6;j++)
{
t<<=1;
t+=(map[i][j]-'0');
}
return t;
}
inline void changetomap(unsigned int t)
{
for(int i=3;i>=0;i--)
for(int j=5;j>=0;j--)
{
map[i][j]= (t&1)+'0';
t>>=1;
}
}
inline void TurnL(int x)
{
char c=map[x][0];
for(int i=0;i<5;i++)
map[x][i]=map[x][i+1];
map[x][5]=c;
}
inline void TurnR(int x)
{
char c=map[x][5];
for(int i=5;i>=1;i--)
map[x][i]=map[x][i-1];
map[x][0]=c;
}
inline void TurnU(int x)
{
char c=map[0][x];
for(int i=0;i<3;i++)
map[i][x]=map[i+1][x];
map[3][x]=c;
}
inline void TurnD(int x)
{
char c=map[3][x];
for(int i=3;i>=1;i--)
map[i][x]=map[i-1][x];
map[0][x]=c;
}
void BFS(unsigned int f)
{
queue<unsigned int> Q;
Q.push(f);
step[f]=0;
unsigned int temp;
unsigned int t=0;
while(!Q.empty())
{
temp=Q.front();
Q.pop();
changetomap(temp);
for(int i=0;i<6;i++)
{
TurnU(i);
t=changetostate();
if(step[t]==-1)
{
Q.push(t);
step[t]=step[temp]+1;
}
TurnD(i);
TurnD(i);
t=changetostate();
if(step[t]==-1)
{
Q.push(t);
step[t]=step[temp]+1;
}
TurnU(i);
}
for(int i=0;i<4;i++)
{
TurnR(i);
t=changetostate();
if(step[t]==-1)
{
Q.push(t);
step[t]=step[temp]+1;
}
TurnL(i);
TurnL(i);
t=changetostate();
if(step[t]==-1)
{
Q.push(t);
step[t]=step[temp]+1;
}
TurnR(i);
}
}
}
int main()
{
int cas=0,T;
init();
BFS(changetostate());
scanf("%d",&T);
while(T--)
{
for(int i=0;i<4;i++)
scanf("%s",map[i]);
printf("Case %d: ",++cas);
int ans=INT_MAX;
unsigned int t;
for(int i=0;i<3;i++)
{
t=0;
for(int j=0;j<4;j++)
for(int k=0;k<6;k++)
{
t<<=1;
if(map[j][k]==hash1[i])
t+=1;
}
if(ans>step[t])
ans=step[t];
}
printf("%d\n",ans);
}
return 0;
}