题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1166
1,用两个bit存储每个表的状态,涉及到位操作
2,将指定位置1,用或操作,A*B(*代表0或者1,A为前缀,B为后缀),将*置1要用C1D(C和D是全0段,两者的长度与A和B对应相等),只要将A*B与C1D相或即可得到A1B
3,将指定位置0,用与操作,A*B,将*置0要用C0D(C和D是全1段,两者的长度与A和B对应相等),只要将A*B与C0D相与即可得到A0B
4,为了方便实现2和3描述的操作用了两个辅助数组set和reset,两者可以通过基本的位运算符求取
5,还有一个比较重要的是位运算符的优先级很低的,要用括号调整
6,一直错,还是广搜代码没有写对,应该入队就设标志位,不能推迟到出队才设置!
#include <iostream>
using namespace std;
#define MAX 2000000
int set[32];
int reset[32];
void Init()
{
int i,tmp;
tmp = 1;
for(i = 0;i < 32;++i)
{
set[i] = tmp;
reset[i] = ~tmp;
tmp <<= 1;
}
}
struct Clock
{
int time;
int pre;
int step;
void Reset(int i)
{
time &= reset[i];
}
void Set(int i)
{
time |= set[i];
}
void Rotate(int i)
{
int b = i*2;
if((set[b] & time) != 0)
Reset(b);
else if(((set[b] & time) == 0) && ((set[b+1] & time) == 0))
{
Set(b);
Set(b+1);
}
else
{
Set(b);
Reset(b+1);
}
}
};
Clock q[MAX];
int hd,tl;
bool visit[MAX],first;
void Print(int i)
{
if(q[i].pre != -1)
{
Print(q[i].pre);
if(first)
{
cout << q[i].step;
first = false;
}
else
cout << ' ' << q[i].step;
}
}
void BFS(Clock& tar)
{
memset(visit,0,sizeof(visit));
Clock cur,next;
cur.time = 0;
cur.pre = -1;
hd = tl = 0;
q[tl++] = cur;
visit[cur.time] = true;
int i;
while(hd != tl)
{
cur = q[hd++];
for(i = 1;i <= 9;++i)
{
next = cur;
switch(i)
{
case 1:
next.Rotate(0);
next.Rotate(1);
next.Rotate(3);
next.Rotate(4);
next.step = 1;
break;
case 2:
next.Rotate(0);
next.Rotate(1);
next.Rotate(2);
next.step = 2;
break;
case 3:
next.Rotate(1);
next.Rotate(2);
next.Rotate(4);
next.Rotate(5);
next.step = 3;
break;
case 4:
next.Rotate(0);
next.Rotate(3);
next.Rotate(6);
next.step = 4;
break;
case 5:
next.Rotate(1);
next.Rotate(3);
next.Rotate(4);
next.Rotate(5);
next.Rotate(7);
next.step = 5;
break;
case 6:
next.Rotate(2);
next.Rotate(5);
next.Rotate(8);
next.step = 6;
break;
case 7:
next.Rotate(3);
next.Rotate(4);
next.Rotate(6);
next.Rotate(7);
next.step = 7;
break;
case 8:
next.Rotate(6);
next.Rotate(7);
next.Rotate(8);
next.step = 8;
break;
case 9:
next.Rotate(4);
next.Rotate(5);
next.Rotate(7);
next.Rotate(8);
next.step = 9;
break;
}
if(!visit[next.time])
{
next.pre = hd-1;
q[tl++] = next;
visit[next.time] = true;
if(next.time == tar.time)
break;
}
}
if(q[tl-1].time == tar.time)
break;
}
first = true;
Print(tl-1);
}
int main()
{
freopen("in.txt","r",stdin);
Init();
Clock c;
int i,b,time[9];
while(true)
{
for(i = 0;i < 9;++i)
cin >> time[i];
if(!cin.good())
break;
c.time = 0;
for(i = 0;i < 9;++i)
{
b = i*2;
switch(time[i])
{
case 0:
c.Reset(b);
c.Reset(b+1);
break;
case 1:
c.Set(b);
c.Reset(b+1);
break;
case 2:
c.Reset(b);
c.Set(b+1);
break;
case 3:
c.Set(b);
c.Set(b+1);
break;
}
}
BFS(c);
cout << endl;
}
return 0;
}