uvaoj 321 - The New Villa
来源:互联网 发布:心灵想要大声呼喊知乎 编辑:程序博客网 时间:2024/06/07 03:38
传送:点击打开链接
一道容易题,弄了我好久啊,各种粗心,郁闷死了!
题意:给三个整数,分别表示:房间数,图的连接情况,每个房间能控制的灯。输出从起点到终点的方式。
搜索很好理解,关键是判重。
可以将灯的情况抽象成01串,人处在的房间号放在房间数+1的位置
例如第一个样例 3个房间初始就可以用 1 0 0 1表示,终点就是 0 0 1 3
再例如10 起点就是 1 0 0 0 0 0 0 0 0 0 1 终点就是0 0 0 0 0 0 0 0 0 1 10
然后再通过转换成10进制对应判重就可以了。
注意考虑房间只有1个的时候。
#include<cstdio>#include<string>#include<cstring>using namespace std;#define MAXN 50000 //其实不用这么大,2^10-1+10*2^10应该就够了int map[12][12];int light[12][12];char vis[MAXN];int n,d,k;int end;struct node{ int dis; int light[12];}q[MAXN];int path[MAXN];int fa[MAXN];int ok;int base[]={0,1,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10}; //通过二进制转换成十进制将每个房间的灯+人的位置的情况与某个整数一一对应int hash(int *a){ int s=0; for(int i=1;i<=n+1;i++) { s+=(a[i]*base[i]); } if(s==end) ok=1; return s;}int bfs(){ int rear=1,front=1; memset(q[1].light,0,sizeof(q[1].light)); vis[1+base[n+1]]=1; q[1].light[1]=1; q[1].light[n+1]=1; q[1].dis=0; fa[1]=0; node tmp; rear++; while(front<rear) { tmp=q[front]; for(int i=1;i<=n;i++) //把当前房间能控制的灯打开或关上 { if(light[tmp.light[n+1]][i]&&tmp.light[n+1]!=i) { node tt=tmp; tt.light[i]=1-tt.light[i]; int x=hash(tt.light); if(!vis[x]) { vis[x]=1; tt.dis++; fa[rear]=front; if(!tt.light[i]) path[rear]=-i*1000; //开关灯保存在百位和千位,负数表示关(纯属个人喜好=_=) else path[rear]=i*1000; q[rear++]=tt; if(ok) {return rear-1;} } } } for(int i=1;i<=n;i++) //能走到的所有房间 { if(map[tmp.light[n+1]][i]&&tmp.light[i]) { node tt=tmp; tt.light[n+1]=i; int x=hash(tt.light); if(!vis[x]) { vis[x]=1; tt.dis++; fa[rear]=front; path[rear]=i; //走到某个房间保存在个位和十位 q[rear++]=tt; if(ok) {return rear-1;} } } } front++; } return -1;}void print(int k){ if(!fa[k]) return; print(fa[k]); if(path[k]<1000&&path[k]>0) printf("- Move to room %d.\n",path[k]); else if(path[k]>0) printf("- Switch on light in room %d.\n",path[k]/1000); else printf("- Switch off light in room %d.\n",(-path[k])/1000);}int main(){ int cas=1; int a,b; while(scanf("%d%d%d",&n,&d,&k)){ ok=0;if(n==0&&d==0&&k==0) break;memset(map,0,sizeof(map));memset(light,0,sizeof(light));memset(vis,0,sizeof(vis)); for(int i=1;i<=d;i++) { scanf("%d%d",&a,&b); map[a][b]=map[b][a]=1; } for(int i=1;i<=k;i++) { scanf("%d%d",&a,&b); light[a][b]=1; } printf("Villa #%d\n",cas++); if(n==1) {printf("The problem can be solved in 0 steps:\n\n");continue;} //注意考虑房间只有1个的情况! end=base[n]+n*base[n+1]; int flag=bfs(); if(flag<0) printf("The problem cannot be solved.\n"); else { printf("The problem can be solved in %d steps:\n",q[flag].dis); print(flag); } putchar(10);} return 0;}
- uvaoj 321 - The New Villa
- 321 - The New Villa
- uva 321 - The New Villa
- UVa 321 - The New Villa
- UVA 321 - The New Villa
- uva 321 - The New Villa
- uva 321 The New Villa
- UVa 321 - The New Villa
- UVA - 321 The New Villa
- uva 321 - The New Villa bfs+递归
- uva:321 - The New Villa(bfs + 哈希判重)
- UVa 321 & ZOJ 1301 - The New Villa
- UVA - 321 The New Villa 隐式图搜索
- The New Villa (Uva 321 bfs)
- zoj1301 The New Villa
- POJ 1137 The New Villa
- [ZOJ1301][POJ1137] The New Villa
- POJ 1137----The New Villa
- Ruby on Rails(ROR)——提高rails new时bundle install运行速度
- 存储优化
- c++ builder OLE创建Excel表格
- 传统table开发和当前流行的div+css开发模式的比较
- 主流android手机分辨率的调研情况
- uvaoj 321 - The New Villa
- python-django返回JSON,实用AJAX
- git,提交更新到本地 origin master 分支
- linux中进程上下文 中断上下文
- Java IO _压缩流
- java类型转换
- Non-blocking I/O and select()
- 一个通用的LINUX驱动Makefile
- Play Framework常用标签list,set,如何遍历list、map类型数据