321UVA【错误原因】怕黑先生别墅找卧室

正确:

#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);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值