题目大意:求将一个r*c的按钮矩阵由全部为关变成全部为开的最少按扭次数,每按一次开关能作用到的范围不定。

题目分析:开关问题。打眼一看就是BFS+位压缩,但是写出来之后TLE。用DFS不断更新最优解。最坏有2^25种情况,加两个剪枝:

  一、每一个开关最多只能影响三行,当第now_r-2行仍然有开关关着,则这种方案不可能使所有按钮全部打开,剪掉(并且是主剪);

  二、当当前总的按按钮次数大于已经达到的答案,则剪掉;

第二个剪枝效果不强,加不加都是26ms过,但不加第一个剪枝一定TLE。

这道题用BFS的话,上面两个剪枝起不到作用。

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<map>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;
struct XY
{
int x,y;
XY(int _x,int _y):x(_x),y(_y){}
};
char pos[3][3];
int cnt,r,c,mark[26];
bool flag;
vector<XY>d;
map<int,char>mp;
string ans;
void init()
{
d.clear();
for(int i=0;i<3;++i){
for(int j=0;j<3;++j){
if(pos[i][j]=='*')
d.push_back(XY(i-1,j-1));
}
}
}
bool ok()
{
for(int i=1;i<=r*c;++i)
if(mark[i]%2==0)
return false;
return true;
}
bool still_unlit(int row)
{
for(int i=(row-1)*c+1;i<=row*c;++i)
if(mark[i]%2==0)
return true;
return false;
}
int get_row(int n)
{
return (n%c)?(n/c)+1:(n/c);
}
void dfs(int id,string have)
{
if(ok()){
if(!flag){
flag=true;
ans=have;
}
else{
if(ans.size()>have.size())
ans=have;
}
return ;
}
if(id>c*2&&still_unlit(get_row(id-c*2)))
return ;
if(flag&&have.size()>ans.size())
return ;
for(int i=id+1;i<=r*c;++i){
int x=get_row(i),y=(i%c)?(i%c):c;
for(int j=0;j<d.size();++j){
int nx=x+d[j].x,ny=y+d[j].y,nid=(nx-1)*c+ny;
if(nx>=1&&nx<=r&&ny>=1&&ny<=c&&nid>=1&&nid<=r*c)
++mark[nid];
}
dfs(i,have+mp[i]);
for(int j=0;j<d.size();++j){
int nx=x+d[j].x,ny=y+d[j].y,nid=(nx-1)*c+ny;
if(nx>=1&&nx<=r&&ny>=1&&ny<=c&&nid>=1&&nid<=r*c)
--mark[nid];
}
}
}
int main()
{
for(int i=1;i<=26;++i)
mp[i]=i+'A'-1;
int cas=0;
while(scanf("%d%d",&r,&c)&&r+c)
{
for(int i=0;i<3;++i)
scanf("%s",pos[i]);
printf("Case #%d\n",++cas);
init();
memset(mark,0,sizeof(mark));
flag=false;
dfs(0,"");
if(flag){
for(int i=0;i<ans.size();++i)
printf("%d%c",ans[i]-'A'+1,(i==ans.size()-1)?'\n':' ');
}else
printf("Impossible.\n");
}
return 0;
}

  

UVA-10318 Security Panel (DFS+剪枝)的更多相关文章

  1. UVA 10318 Security Panel(DFS剪枝 + 状压 + 思维)题解

    题意:给一个r*c的矩阵开关(初始全打开的),每次按下一个开关都会改变3*3范围内的有*的地方的状态,问你最少几步能让开关全闭上,按升序输出按哪些按钮 思路:每个按钮至多按一下,按按钮的顺序和结果无关 ...

  2. UVa 10318 Security Panel

    题意:给你一个3*3的翻转模版,深色部分表示翻转,浅色部分不变.然后你可以在r*c的矩形里依照模版进行翻转,要求所有点亮所有块.输出最小的步骤. 思路:有一点比较好想.每个块至多被翻转一次,翻两次的效 ...

  3. UVa 208 消防车(dfs+剪枝)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVA 140 Bandwidth (dfs 剪枝 映射)

    题意: 给定一个n个结点的图G和一个结点的排列, 定义结点i的带宽b(i)为i和相邻结点在排列中的最远距离, 所有b(i)的最大值就是这个图的带宽, 给定G, 求让带宽最小的结点排列. 给定的图 n ...

  5. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  6. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  8. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  9. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  10. DFS+剪枝 HDOJ 5323 Solve this interesting problem

    题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...

随机推荐

  1. java多线程----线程池源码分析

    http://www.cnblogs.com/skywang12345/p/3509954.html 线程池示例 在分析线程池之前,先看一个简单的线程池示例. 1 import java.util.c ...

  2. Redis 如何正确实现分布式锁

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  3. 20145314郑凯杰《网络对抗技术》PE文件病毒捆绑(插入捆绑)的实现

    20145314郑凯杰<网络对抗技术>PE文件病毒捆绑(插入捆绑)的实现 一.本节摘要 简介:每个应用程序内部都有一定的空间(因为文件对齐余留的00字段)可以被利用,这样就可以保证被插入的 ...

  4. 20145321《网络对抗技术》逆向与Bof基础

    20145321<网络对抗技术>逆向与Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...

  5. Win10 Edge浏览器怎么重装 Win10重装Edge浏览器

    具体如下: 重新安装Microsoft Edge 1.按Windows键+ R,打开 输入以下代码,可以直接复制黏贴. %LocalAppData%\Packages\Microsoft.Micros ...

  6. 托管C++调用C#

    拿到了一个第三方demo,有dll,有.cpp..h,打开解决方案,如下图: 网上资料貌似很少,根据猜测: 这是使用托管C++来调用C#的方式. 过程: 1.先使用C#代码实现界面和功能,其实就是一个 ...

  7. Python3基础 str while+iter+next 字符串的遍历

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. 三羊献瑞|2015年蓝桥杯B组题解析第三题-fishers

    三羊献瑞 观察下面的加法算式: 祥 瑞 生 辉 三 羊 献 瑞 三 羊 生 瑞 气 (如果有对齐问题,可以参看[图1.jpg]) 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写& ...

  9. 关于ActiveMQ、RocketMQ、RabbitMQ、Kafka一些总结和区别

    这是一篇分享文 转自:http://www.cnblogs.com/williamjie/p/9481780.html  尊重原作,谢谢 消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: ...

  10. 51nod 1266 蚂蚁

    蚂蚁这道题 就是 不管两只蚂蚁相撞  他们会朝自己的反方向走 不过可以这么想  有蚂蚁1 和 蚂蚁2   并且相向而行 如果撞了以后 蚂蚁1和蚂蚁2 就往回走   ,这里可以理解成蚂蚁1,蚂蚁2 继续 ...