The New Villa
题目:The New Villa
题目链接:http://poj.org/problem?id=1137
题目大意:
一个人买了一个别墅,里面有很多房间,特别的是这个别墅的房间里灯的开关是乱套的,也就是说房间1可能没有房间1的灯的开关,而有房间2和房间3的开关,现在从房间1出发,刚开始只有房间1是亮的,只能走到亮着的房间(还必须有门相通),现在问你走到房间n,并且只剩下房间n是亮着的步骤,如果有多个方法,输出步骤最少的。
题目思路:
啥也不说,n最大为10,暴力搜,注意剪枝就可以了。。。附上我的代码和代码解析,不过我的代码并不怎么给力,最后时间还是需要250。。。
1 #include<stdio.h> 2 #include<string.h> 3 bool door[11][11]; //门 4 bool sw[11][11]; //如果i能控制j的灯,那么sw[i][j]=1 5 int light; //当前灯的状态,从0到1024 6 int n; //房间的总数量 7 int count[11][11]; //某一扇门被经过的次数,可以用来控制递归次数,减少时间 8 int num[11]; //记录房间开关的所有状态数量,达不到1024 9 int nu[11][1024]; //记录每个房间开关的所有状态 10 bool OK() //判断是否只有卧室灯开着,结束判断为当前位置为卧室且OK() 11 { 12 if(light^(1<<(n-1))) return false; 13 return true; 14 } 15 void Init() //初始化,处理每个房间开关可能的状态 16 { 17 for(int i=1;i<=n;i++) 18 { 19 for(int j=0;j<1024;j++) 20 { 21 if((1<<(i-1))&j) continue; //不允许关掉自己房间的灯 22 int o; 23 for(o=1;o<11;o++) 24 { 25 if(sw[i][o]==1) continue; 26 if((1<<(o-1))&j) break; //如果没有该房间的控制权,不允许对其进行操作 27 } 28 if(o<11) continue; 29 nu[i][num[i]++]=j; 30 } 31 } 32 } 33 void dis(int tmp) //测试用。。。。 34 { 35 int co=0; 36 while(tmp) 37 { 38 printf("%d ",tmp&1); 39 tmp>>=1; 40 co++; 41 } 42 co=11-co; 43 while(co--) 44 { 45 printf("0 "); 46 } 47 printf("\n"); 48 } 49 50 int s[10000][2]; //保存当前的步骤情况 51 int mint[10000][2],mino; //保存所有能成功的步骤中步骤最小的 52 bool v[11][1024]; //保存是否遇到过这种情况,与下面的结合使用 53 int vum[11][1024]; //vum[i][j]表示当前处在房间i,灯的状态为j,最小的步骤,剪枝用 54 bool match; //是否能完成任务 55 void DFS(int i,int step) 56 { 57 if(v[i][light]&&step>=vum[i][light]) return ; 58 //因为下面有个剪枝,通过0状态过去的和这个一样。不在这里刷新值是为了在下面的可以把step>=的都排除掉,更快。 59 for(int j=0;j<num[i];j++) 60 { 61 int k=nu[i][j]; //可行的开关执行方案 62 int tmp=light; //保存原来的灯状态 63 light^=k; //操作开关 64 int pre_step=step; //保存原来的步骤 65 for(int o=1;o<=n;o++) //记录步骤 66 { 67 if((1<<(o-1))&k) 68 { 69 s[step++][0]=o; 70 } 71 } 72 if(v[i][light]&&step>=vum[i][light]) //剪枝 73 { 74 light=tmp; 75 step=pre_step; 76 continue; 77 } 78 v[i][light]=1; 79 vum[i][light]=step; 80 if(i==n&&OK()) //如果完成操作 81 { 82 if(step<mino) 83 { 84 for(int o=0;o<step;o++) 85 { 86 mint[o][0]=s[o][0]; 87 mint[o][1]=s[o][1]; 88 } 89 mino=step; 90 } 91 match=1; 92 light=tmp; 93 return ; 94 } 95 for(int j=1;j<=n;j++) 96 { 97 if(door[i][j]==1&&(light&(1<<(j-1)))) //如果有门相通 98 { 99 count[i][j]++; 100 if(count[i][j]>n-1) 101 { 102 count[i][j]--; 103 continue; 104 } 105 s[step][1]=j; 106 DFS(j,step+1); //进入下一个房间 107 s[step][1]=-1; //只在这里进行恢复,因为这里的恢复比恢复s[step][0]的快很多 108 count[i][j]--; 109 } 110 } 111 light=tmp; 112 step=pre_step; 113 } 114 } 115 void solve() //展示步骤 116 { 117 int light=1; 118 printf("The problem can be solved in %d steps:\n",mino); 119 for(int i=0;i<mino;i++) 120 { 121 if(mint[i][1]==-1) 122 { 123 if(light&(1<<(mint[i][0]-1))) 124 { 125 printf("- Switch off light in room %d.\n",mint[i][0]); 126 } 127 else 128 { 129 printf("- Switch on light in room %d.\n",mint[i][0]); 130 } 131 light^=(1<<(mint[i][0]-1)); 132 } 133 else 134 { 135 printf("- Move to room %d.\n",mint[i][1]); 136 } 137 } 138 } 139 int main() 140 { 141 int m,k,a,b,cas=1; 142 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 143 { 144 if(n==0&&m==0&&k==0) break; 145 memset(door,0,sizeof(door)); 146 for(int i=0;i<m;i++) 147 { 148 scanf("%d%d",&a,&b); 149 door[a][b]=1; 150 door[b][a]=1; 151 } 152 memset(sw,0,sizeof(sw)); 153 memset(num,0,sizeof(num)); 154 for(int i=0;i<k;i++) 155 { 156 scanf("%d%d",&a,&b); 157 sw[a][b]=1; 158 } 159 Init(); 160 light=1; 161 memset(s,-1,sizeof(s)); 162 mino=100000; 163 match=0; 164 memset(v,0,sizeof(v)); 165 DFS(1,0); 166 printf("Villa #%d\n",cas++); 167 if(match==1) 168 { 169 solve(); 170 printf("\n"); 171 } 172 else printf("The problem cannot be solved.\n\n"); 173 } 174 return 0; 175 }
转载于:https://www.cnblogs.com/hchlqlz-oj-mrj/p/5075150.html
The New Villa相关推荐
- UVA 321 The New Villa
UVA_321 这个题目可以把所有灯的开关状态以及当前人所在的屋子看成一个状态,这样的话最多只有n*2^n个状态,由于n很小,还是可以接受的,直接进行隐式图搜索即可. 在用Hash判重时,为了方便我们 ...
- 拜读近五年UT Austin Villa发表的RoboCup仿真3D论文
前言: UT Austin Villa是近几年Robocup仿真3D项目中稳稳当当的世界冠军,他们每年拿了冠军之后都会发1到2篇论文来阐述他们的进步,其论文内容已经形成了固定模板.首先是Introdu ...
- UVa 321 The New Villa,2B青年怒找卧室
题目链接: UVA : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24 ...
- 教主的别墅(villa)
第三题:教主的别墅(villa) (villa.pas/cpp/in/out) villa.in villa.out [题目背景] LHX教主身为宇宙第一富翁,拥有一栋富丽堂皇的别墅,由于别墅实在太大 ...
- 被解放的姜戈02 庄园疑云
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上一回说到,姜戈的江湖初体验:如何架设服务器,如何回复http请求,如何创建App ...
- 一文览尽ToF深度相机技术
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 摘要:现行专业级或消费级的3D相机所采用的三角法(Triangulation)和飞时法(Time-of ...
- Cell子刊:源自微生物群的醋酸盐能够在健康和疾病期间促进大脑先天免疫系统的代谢适应性...
源自微生物群的醋酸盐能够在健康和疾病期间促进大脑先天免疫系统的代谢适应性 Microbiota-derived acetate enables the metabolic fitness of the ...
- 这几个模型不讲“模德”,我劝它们耗子尾汁
点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 文 | Sheryc_王苏 NLP模型要以和为贵,要讲"模德"(M ...
- 万字深度好文!视觉-语言(VL)智能:任务、表征学习和大型模型
来源:AI科技评论 编译:Jocelyn 编辑:陈彩娴 本文对视觉-语言(VL)智能按时间顺序进行了全面调研,并将这一领域的发展总结为三个阶段: 第一个阶段是2014-2018年,其间,专门的模型被设 ...
- ACM题集以及各种总结大全(转)
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...
最新文章
- php用正则_php 正则表达式匹配(持续更新)
- 大数据科学认识与理解论坛全攻略
- iis6上安装PHP5.3.2及连接到SQL Server 2005/2008的设置(原创)
- java虚拟机编译_[四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式...
- bp 神经网络 优点 不足_基于粒子群算法和BP神经网络的多因素林火等级预测模型...
- Page_PreInit在网页传值的应用
- mybatis3.1-[topic-16-17]-映射文件_增删改查_insert_获取自增主键的值
- window下spark的安装和开发环境配置
- Jim Marino与Meeraj Kunnumpurath专访:关于SCA和Fabric3
- 编程珠玑续版-chp2 关联数组-awk
- Linux系统Ubuntu安装kvaser Leaf Light V2驱动
- 矩阵乘法计算量估算/华为机试(C/C++)
- mzy对于枚举的理解
- 关于烂代码优化重构的几点经验
- k8s DNS服务配置
- node安装与环境搭建 + VUE项目搭建
- DNA存储技术创造新纪录 存储容量已达200MB
- java计算机毕业设计手机电子商城源代码+数据库+系统+lw文档
- 数据库优化问题【刘新宇】
- 福禄克线缆测试的PATCH CORD和CHANNEL是什么
热门文章
- 45. 正确区分count、find、binary_search、lower_bound、upper_bound和equal_range
- 31. 了解各种与排序有关的选择
- 05. 区间成员函数优先于与之对应的单元素成员函数
- matlab 矩阵逻辑与,MATLAB自学笔记(七):数组运算与矩阵操作
- oracle rac vip不通,Oracle RAC 中vip网关引起错误的解决
- Vue:embed结合ElementUI中dialog实现PDF文件预览
- CSS:布局——伸缩布局flex
- python中match用法_python re.match()用法相关示例
- crawler4j源码学习(2):Ziroom租房网房源信息采集爬虫
- Java关键字this与super的用法详解