很BT的搜索。。。
刚开始看题目的时候,也理解了题意,不过没想到要用什么算法。。
也有想到每一种状态都存起来,不过没想到该怎么样处理细节。。最后不得己在网上搜了下代码,。。
这题很BT的,,只是搜索就够麻烦了, 最后还要保存路径。。搞的头大。。
不过最后无论如何还是把它给A了。。。^_^ .
poj上的这道题目貌似不是special judje,,在poj上没能过去。。
题目大意:
黑先生新买了一栋别墅,可是里面的电灯线路的连接是很混乱的,有一天晚上他回家时发现所有的灯(除了他出发的房间)都是关闭的,而他想回卧室去休息。可是很不幸,他十分怕黑,因此他不会走入任何关着灯的房间,于是请你帮他找出一条路使他既能回到卧室又能关闭除卧室以外的所有灯。如果同时有好几条路线的话,请输出最短的路线。
中间有用到位运算,先给列出来。。
1<<n - 1 就是n位都是1
a & (1<<n) 获取 a 的 第 n - 1 位
a | (1<<n) 置a 的第 n 位为1
a ^ (1<<n) 置a 的第 n 位为原来的相反数
代码:
# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<queue>
# define MAX 1100
using namespace std;
struct node{
int room,state,step;
};
queue<node>q;
node cur,next,path[11][MAX];
int r,s,d,visit[12][MAX],adj[12][12],control[12][12],num[MAX],ch;
char ans[MAX][10];
int bfs()
{
int i,temp;
visit[1][1]=1;
cur.room=1;
cur.state=1;
cur.step=0;
while(!q.empty())
q.pop();
q.push(cur);
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.room==r && cur.state==ch) return cur.step;
for(i=1;i<=r;i++)/*先搞开关*/
{
if(cur.room==i || control[cur.room][i]==0) continue;
next=cur;
next.state=(next.state)^(1<<(i-1));/*转换第i个房间的状态*/
if(visit[next.room][next.state]==0)
{
visit[next.room][next.state]=1;
next.step=cur.step+1;
q.push(next);
path[next.room][next.state]=cur;
}
}
/*进入相邻的房间*/
for(i=1;i<=r;i++)
{
if(adj[cur.room][i]==0 || i==cur.room) continue;
next=cur;
next.room=i;
temp=next.state&(1<<(i-1));/*判断第i个房间的灯光*/
if(temp==0) continue;
if(visit[next.room][next.state]==0)
{
visit[next.room][next.state]=1;
next.step=cur.step+1;
q.push(next);
path[next.room][next.state]=cur;
}
}
}
return -1;
}
int main()
{
int i,j,b,a,t=0,temp,top,x,y,k;
while(scanf("%d%d%d",&r,&d,&s)!=EOF)
{
if(r==0 && s==0 && d==0) break;
t++;
printf("Villa #%d\n",t);
memset(adj,0,sizeof(adj));
memset(control,0,sizeof(control));
memset(visit,0,sizeof(visit));
for(i=0;i<=r;i++)
for(j=0;j<=r;j++)
{
path[i][j].room=i;
path[i][j].state=j;
}
for(i=1;i<=d;i++)
{
scanf("%d%d",&a,&b);
adj[a][b]=1;
adj[b][a]=1;
}
for(i=1;i<=s;i++)
{
scanf("%d%d",&a,&b);
control[a][b]=1;
}
ch=1;
for(i=1;i<r;i++)
ch*=2;
temp=bfs();
if(temp==-1)
{
printf("The problem cannot be solved.\n\n");
continue;
}
printf("The problem can be solved in %d steps:\n",temp);
i=r;
j=ch;
top=0;
while(1)
{
if(path[i][j].room==i && path[i][j].state==j) break;
if(path[i][j].room!=i)
{
strcpy(ans[top],"Move");
num[top]=i;
top++;
}
else
{
for(k=0;;k++)
{
x=j&(1<<k);
y=path[i][j].state&(1<<k);
if(x!=y) break;
}
if(x==0)
{
strcpy(ans[top],"off");
num[top]=k+1;
top++;
}
else
{
strcpy(ans[top],"on");
num[top]=k+1;
top++;
}
}
x=path[i][j].room;
y=path[i][j].state;
i=x;
j=y;
}
for(i=top-1;i>=0;i--)
{
if(strcmp(ans[i],"Move")==0)
{
printf("- Move to room %d.\n",num[i]);
}
else if(strcmp(ans[i],"off")==0)
{
printf("- Switch off light in room %d.\n",num[i]);
}
else
{
printf("- Switch on light in room %d.\n",num[i]);
}
}
printf("\n");
}
return 0;
}