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 ...
随机推荐
- 如何在linux平台上编译安装zlib软件(公司部分线上机器缺少zlib不能安装supervisor)
文章在Centos 6.5 linux平台上演示一下如何进行编译安装zlib软件,并配置相关的选项加载使用.示范从下载到安装并配置进行使用过程一系列整套讲解,希望可以给网友考虑使用,谢谢. 工具 ...
- vue中$router.push打开新窗口
在vue中使用 this.$router.push({ path: '/home' }) 默认是替代本窗口 如果想新开一个窗口,可以使用下面的方式: let routeData = this.$ro ...
- 设计模式のPrototypePattern(原型模式)----创建模式
一.产生的背景 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆.当直接创建对象的代价比较大时,则采用这种模式.例如,一个对象需要在一个高代价的数据库操作之后被创建.我们可以缓存该对象,在下 ...
- linux快速搭建
------------------------------------------ 转载内容 --------------------- Linux升级命令有两个分别是yum upgrade和yum ...
- P2819 图的m着色问题(DFS)
思路:最开始的回溯顺序是正常的图遍历的回溯顺序,其实也没有错.但是,因为怎么调都不对,看了题解.下面,请结合题解思路和代码一起感受一下回溯顺序的改变,算法的改变和代码在哪里实现了这种顺序. 回溯顺序: ...
- Python:Day16 闭包、装饰器
def outer(): x = 10 def inner(): #条件一.inner就是一个内部函数 print(x) #条件二.引用外部作用域的一个变量,因为x在函数外部的,所以是外部作用域的变量 ...
- metamask的使用
Metamask 我是在火狐浏览器安装它的,所以一开始安装了Firefox:http://www.firefox.com.cn/ 然后是下载metamask,它的官方网站是https://metama ...
- selenium中遇到div弹框,一起引申到其他弹框
1.div弹框和DOM普通元素一样处理 2.出现一下就自动消失的弹框,也是在DOM中有描述的,可以使用xpath,用其内容定位 3.(转,其他弹框处理,包括alert和不同windows) https ...
- Spring Security(二十七):Part II. Architecture and Implementation
Once you are familiar with setting up and running some namespace-configuration based applications, y ...
- [MicroPython]TPYBoard v102炫彩跑马灯WS2812B
一.实验目的 了解ws2812b的工作原理 学习ws2812b的驱动方法 二.实验器材 TPYBoard v102 1块 ws2812b RGB-Ring-8 1个 micro USB数据线 1条 杜 ...