The New Villa
题目:The New Villa
题目链接:http://poj.org/problem?id=1137
题目大意:
一个人买了一个别墅,里面有很多房间,特别的是这个别墅的房间里灯的开关是乱套的,也就是说房间1可能没有房间1的灯的开关,而有房间2和房间3的开关,现在从房间1出发,刚开始只有房间1是亮的,只能走到亮着的房间(还必须有门相通),现在问你走到房间n,并且只剩下房间n是亮着的步骤,如果有多个方法,输出步骤最少的。
题目思路:
啥也不说,n最大为10,暴力搜,注意剪枝就可以了。。。附上我的代码和代码解析,不过我的代码并不怎么给力,最后时间还是需要250。。。
#include<stdio.h>
#include<string.h>
bool door[][]; //门
bool sw[][]; //如果i能控制j的灯,那么sw[i][j]=1
int light; //当前灯的状态,从0到1024
int n; //房间的总数量
int count[][]; //某一扇门被经过的次数,可以用来控制递归次数,减少时间
int num[]; //记录房间开关的所有状态数量,达不到1024
int nu[][]; //记录每个房间开关的所有状态
bool OK() //判断是否只有卧室灯开着,结束判断为当前位置为卧室且OK()
{
if(light^(<<(n-))) return false;
return true;
}
void Init() //初始化,处理每个房间开关可能的状态
{
for(int i=;i<=n;i++)
{
for(int j=;j<;j++)
{
if((<<(i-))&j) continue; //不允许关掉自己房间的灯
int o;
for(o=;o<;o++)
{
if(sw[i][o]==) continue;
if((<<(o-))&j) break; //如果没有该房间的控制权,不允许对其进行操作
}
if(o<) continue;
nu[i][num[i]++]=j;
}
}
}
void dis(int tmp) //测试用。。。。
{
int co=;
while(tmp)
{
printf("%d ",tmp&);
tmp>>=;
co++;
}
co=-co;
while(co--)
{
printf("0 ");
}
printf("\n");
} int s[][]; //保存当前的步骤情况
int mint[][],mino; //保存所有能成功的步骤中步骤最小的
bool v[][]; //保存是否遇到过这种情况,与下面的结合使用
int vum[][]; //vum[i][j]表示当前处在房间i,灯的状态为j,最小的步骤,剪枝用
bool match; //是否能完成任务
void DFS(int i,int step)
{
if(v[i][light]&&step>=vum[i][light]) return ;
//因为下面有个剪枝,通过0状态过去的和这个一样。不在这里刷新值是为了在下面的可以把step>=的都排除掉,更快。
for(int j=;j<num[i];j++)
{
int k=nu[i][j]; //可行的开关执行方案
int tmp=light; //保存原来的灯状态
light^=k; //操作开关
int pre_step=step; //保存原来的步骤
for(int o=;o<=n;o++) //记录步骤
{
if((<<(o-))&k)
{
s[step++][]=o;
}
}
if(v[i][light]&&step>=vum[i][light]) //剪枝
{
light=tmp;
step=pre_step;
continue;
}
v[i][light]=;
vum[i][light]=step;
if(i==n&&OK()) //如果完成操作
{
if(step<mino)
{
for(int o=;o<step;o++)
{
mint[o][]=s[o][];
mint[o][]=s[o][];
}
mino=step;
}
match=;
light=tmp;
return ;
}
for(int j=;j<=n;j++)
{
if(door[i][j]==&&(light&(<<(j-)))) //如果有门相通
{
count[i][j]++;
if(count[i][j]>n-)
{
count[i][j]--;
continue;
}
s[step][]=j;
DFS(j,step+); //进入下一个房间
s[step][]=-; //只在这里进行恢复,因为这里的恢复比恢复s[step][0]的快很多
count[i][j]--;
}
}
light=tmp;
step=pre_step;
}
}
void solve() //展示步骤
{
int light=;
printf("The problem can be solved in %d steps:\n",mino);
for(int i=;i<mino;i++)
{
if(mint[i][]==-)
{
if(light&(<<(mint[i][]-)))
{
printf("- Switch off light in room %d.\n",mint[i][]);
}
else
{
printf("- Switch on light in room %d.\n",mint[i][]);
}
light^=(<<(mint[i][]-));
}
else
{
printf("- Move to room %d.\n",mint[i][]);
}
}
}
int main()
{
int m,k,a,b,cas=;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if(n==&&m==&&k==) break;
memset(door,,sizeof(door));
for(int i=;i<m;i++)
{
scanf("%d%d",&a,&b);
door[a][b]=;
door[b][a]=;
}
memset(sw,,sizeof(sw));
memset(num,,sizeof(num));
for(int i=;i<k;i++)
{
scanf("%d%d",&a,&b);
sw[a][b]=;
}
Init();
light=;
memset(s,-,sizeof(s));
mino=;
match=;
memset(v,,sizeof(v));
DFS(,);
printf("Villa #%d\n",cas++);
if(match==)
{
solve();
printf("\n");
}
else printf("The problem cannot be solved.\n\n");
}
return ;
}
The New Villa的更多相关文章
- ZOJ 1301 The New Villa (BFS + 状态压缩)
题意:黑先生新买了一栋别墅,可是里面的电灯线路的连接是很混乱的(每个房间的开关可能控制其他房间,房间数<=10),有一天晚上他回家时发现所有的灯(除了他出发的房间)都是关闭的,而他想回卧室去休息 ...
- 【BFS】The New Villa
[poj1137] The New Villa Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1481 Accepted ...
- AssetBundle loading failed because.....已解决
http://blog.csdn.net/ldghd/article/details/9632455 ***************************** 一 ******* ...
- Chrome开发者工具之JavaScript内存分析
阅读目录 对象大小(Object sizes) 对象的占用总内存树 支配对象(Dominators) V8介绍 Chrome 任务管理器 通过DevTools Timeline来定位内存问题 内存回收 ...
- 如何解决winows启动后出现grub?
village :村庄, 村民 villa: 别墅 setting: 设置; ** 环境, 背景, 布置, 布局, 底座 what's the setting of the villa like? h ...
- [转载]JavaScript内存分析
https://github.com/CN-Chrome-DevTools/CN-Chrome-DevTools/blob/master/md/Performance-Profiling/javasc ...
- 二分图------》Hopcroft-Karp算法 hdu2389
Hopcroft-Karp算法 该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法. 原理 为了降低时间复杂度,可以在增广匹配集合M ...
- UI中经常出现的下拉框下拉自动筛选效果的实现
小需求是当你在第一个下拉框选择了国家时,会自动更新第二个省份的下拉框,效果如下 两个下拉选择Html如下: <select id="country_select"> & ...
- UVA题目分类
题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...
随机推荐
- Maven将中央仓库修改为阿里云的仓库地址
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexu ...
- 查看linux中的TCP连接数
一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议 ...
- 移动端rem flexible方案
一.px 自动转换为rem sublim Text3 下载本项目,比如:git clone https://github.com/flashlizi/cssrem 进入packages目录(在Subl ...
- iptables nat 技术转发
NAT 一. 什么是 NAT NAT(Network Address Translation)译为网络地址转换.通常路由器在转发我们的数据包时,仅仅会将源MAC地址换成自己的MAC地址,但是NAT技术 ...
- pycharm企业版注册码
pycharm下载最新版 链接:https://pan.baidu.com/s/1gKOCf3PQFc1_2amkMUU1-A 提取码:9pt0 下载企业版: http://www.jetbrains ...
- Python:Day53 Template基础
一.模板由 html代码+逻辑控制代码 组成 二.逻辑控制代码的组成 1.变量(使用双大括号来引用变量) 语法格式:{{ var_name }} -----------------------Temp ...
- hdu4966 GGS-DDU
hdu4966 GGS-DDU 有 \(n\) 个课程,每种课程有 \(a_i\) 级,一开始你每种课程都为 \(0\) 级,有 \(m\) 个升级方案:\((x,\ l1,\ y,\ l2,\ c) ...
- nginx + tomcat = http && https
Tomcat版块配置: vim /to/path/conf/server.xml <Server port="" shutdown="SHUTDOWN"& ...
- linux内存源码分析 - 内存回收(匿名页反向映射)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 看完了内存压缩,最近在看内存回收这块的代码,发现内容有些多,需要分几块去详细说明,首先先说说匿名页的反向映 ...
- ESP8266开发综合篇第一节(LUA)-下载和刷固件
本节视频: https://v.youku.com/v_show/id_XNDAwMTI2OTg2MA==.html?spm=a2h3j.8428770.3416059.1 一,整版测试 刷入测试固 ...