正确:
#include<stdio.h>
#include<string.h>
//1:“move from one room to another”
//2:“switch on a light”
//3:“switch off a light”
const int maxstate=300000; //30000
const int maxhash=30000;
typedef int State[10];
int op[maxstate];
int fa[maxstate];
int step[maxstate];
int pos[maxstate];
State que[maxstate];
int r,d,s;
bool door[15][15];
bool swi[15][15];
State goal,ini;
int head[maxhash];
int next[maxstate];
int hashv(State& s,int pos)
{
int v=0;
for(int i=r-1;i>=0;i--)
{
v=v*2+s[i];
}
v=v*2+pos;
return v%maxhash;
}
bool tryinsert(int id)
{
int h=hashv(que[id],pos[id]);
int u=head[h];
while(u)
{
if(0==memcmp(&que[id],&que[u],sizeof(State))&&pos[id]==pos[u])
return false;
u=next[u];
}
next[id]=head[h];
head[h]=id;
return true;
}
int bfs()
{
memset(head,0,sizeof(head));
int front,rear;
front=rear=1;
op[rear]=0;
fa[rear]=1;
step[rear]=0;
pos[rear]=0;
memcpy(&que[rear],&ini,sizeof(State));
rear++;
while(front<rear)
{
State& s=que[front];
int spos=pos[front];
if(spos==r-1 && 0==memcmp(&que[front],&goal,sizeof(State)) )
return front;
//move to another lighted room
for(int i=0;i<r;i++)
{
if(door[spos][i]&&s[i])
{
op[rear]=10+i;
fa[rear]=front;
step[rear]=step[front]+1;
pos[rear]=i;
memcpy(&que[rear],&s,sizeof(State));
if(tryinsert(rear))
{
rear++;
}
}
}
//switch light on/off
for(int i=0;i<r;i++)
{
if(swi[spos][i]) //CRASH!
{
if(i==spos) continue;
if(s[i]==0) //on:2
op[rear]=20+i;
else
op[rear]=30+i;
fa[rear]=front;
step[rear]=step[front]+1;
pos[rear]=spos;
memcpy(&que[rear],&s,sizeof(State));
que[rear][i] = (!que[rear][i]);
if(tryinsert(rear))
{
rear++;
}
}
}
front++;
}
return -1;
}
void print(int id)
{
if(fa[id]!=id)
{
print(fa[id]);
int choose=op[id]/10;
switch(choose)
{
case 1:
printf("- Move to room %d.\n",op[id]%10+1);
break;
case 2:
printf("- Switch on light in room %d.\n",op[id]%10+1);
break;
case 3:
printf("- Switch off light in room %d.\n",op[id]%10+1);
break;
}
}
}
int main()
{
//
freopen("input.txt","r",stdin);
freopen("out.txt","w",stdout);
int numcase=1;
int u,v;
while(scanf("%d%d%d",&r,&d,&s)==3)
{
if(!r&&!d&&!s) break;
memset(door,false,sizeof(door));
memset(swi,false,sizeof(swi));
for(int i=0;i<d;i++)
{
scanf("%d%d",&u,&v);
door[u-1][v-1]=door[v-1][u-1]=true;
}
for(int i=0;i<s;i++)
{
scanf("%d%d",&u,&v);
swi[u-1][v-1]=true;
}
memset(goal,0,sizeof(goal));
memset(ini,0,sizeof(ini));
goal[r-1]=1;
ini[0]=1;
int res = bfs();
printf("Villa #%d\n",numcase++);
/* adding this is also right
if(r==1)
{
printf("The problem can be solved in %d steps:\n",0);
putchar(10);
continue;
}
*/
if(res==-1)
printf("The problem cannot be solved.\n");
else
{
printf("The problem can be solved in %d steps:\n",step[res]);
print(res);
}
putchar(10);
}
}
错误:
#include<stdio.h>
#include<string.h>
//1:“move from one room to another”
//2:“switch on a light”
//3:“switch off a light”
const int maxstate=30000;
const int maxhash=30000;
typedef int State[10];
int op[maxstate];
int fa[maxstate];
int step[maxstate];
int pos[maxstate];
State que[maxstate];
int r,d,s;
bool door[15][15];
bool swi[15][15];
State goal,ini;
int head[maxhash];
int next[maxstate];
int hashv(State& s,int pos)
{
int v=0;
for(int i=0;i<r;i++)
{
v=v*2+s[i];
}
v=v+pos*3;
return v%maxhash;
}
bool tryinsert(int id)
{
int h=hashv(que[id],pos[id]);
int u=head[h];
while(u)
{
if(0==memcmp(&que[id],&que[u],sizeof(State))&&pos[id]==pos[u])
return false;
u=next[u];
}
next[id]=head[h];
head[h]=id;
return true;
}
int bfs()
{
memset(head,0,sizeof(head));
int front,rear;
front=rear=1;
op[rear]=1;
fa[rear]=1;
step[rear]=0;
pos[rear]=0;
memcpy(&que[rear],&ini,sizeof(State));
rear++;
while(front<rear)
{
State& s=que[front];
int spos=pos[front];
if(spos==r-1 && 0==memcmp(&que[front],&goal,sizeof(State)) )
return front;
//move to another lighted room
for(int i=0;i<r;i++)
{
if(door[spos][i]&&s[i])
{
op[rear]=10+i;
fa[rear]=front;
step[rear]=step[front]+1;
pos[rear]=i;
memcpy(&que[rear],&s,sizeof(State));
if(tryinsert(rear))
{
rear++;
}
}
}
//switch light on/off
for(int i=0;i<r;i++)
{
if(swi[spos][i]) //CRASH!
{
if(i==spos) continue;
if(s[i]==0) //on:2
op[rear]=20+i;
else
op[rear]=30+i;
fa[rear]=front;
step[rear]=step[front]+1;
pos[rear]=spos;
memcpy(&que[rear],&s,sizeof(State));
que[rear][i] = (!que[rear][i]);
if(tryinsert(rear))
{
rear++;
}
}
}
front++;
}
return -1;
}
void print(int id)
{
if(fa[id]!=id)
{
print(fa[id]);
int choose=op[id]/10;
switch(choose)
{
case 1:
printf("- Move to room %d.\n",op[id]%10+1);
break;
case 2:
printf("- Switch on light in room %d.\n",op[id]%10+1);
break;
case 3:
printf("- Switch off light in room %d.\n",op[id]%10+1);
break;
}
}
}
int main()
{
//
freopen("input.txt","r",stdin);
freopen("out.txt","w",stdout);
int numcase=1;
int u,v;
while(scanf("%d%d%d",&r,&d,&s)==3)
{
memset(door,false,sizeof(door));
memset(swi,false,sizeof(swi));
if(!r&&!d&&!s) break;
for(int i=0;i<d;i++)
{
scanf("%d%d",&u,&v);
door[u-1][v-1]=door[v-1][u-1]=true;
}
for(int i=0;i<s;i++)
{
scanf("%d%d",&u,&v);
swi[u-1][v-1]=true;
}
for(int i=0;i<r;i++)
{
if(i==0)
{
goal[i]=0;
ini[i]=1;
continue;
}
if(i==r-1)
{
goal[i]=1;
ini[i]=0;
continue;
}
goal[i]=0;
ini[i]=0;
}
int res = bfs();
printf("Villa #%d\n",numcase++);
if(r==1)
{
printf("The problem can be solved in %d steps:\n",0);
putchar(10);
continue;
}
if(res==-1)
printf("The problem cannot be solved.\n");
else
{
printf("The problem can be solved in %d steps:\n",step[res]);
print(res);
}
putchar(10);
}
}