UVA 10318 Security Panel(DFS剪枝 + 状压 + 思维)题解
题意:给一个r*c的矩阵开关(初始全打开的),每次按下一个开关都会改变3*3范围内的有*的地方的状态,问你最少几步能让开关全闭上,按升序输出按哪些按钮
思路:每个按钮至多按一下,按按钮的顺序和结果无关。我们把当前矩阵的开关状态状压到 long long,并且预处理按下每个按钮的变化,这样可以直接异或得到新的状态。这里还需要剪枝,因为顺序无关,我们直接从1按到r*c,那么如果我们按到第k行,现在就已经影响不到k-2行了,所以k-2行如果有开关没闭上就return。
代码:
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1e5 + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
int r, c;
char s[][];
ll change[], ansStep[], step[], vis[][], lit, ansCnt, cnt, OK;
void init(int x, int y){
int pos = (x - ) * c + y;
change[pos] = ;
for(int i = ; i <= ; i++){
for(int j = ; j <= ; j++){
if(s[i][j] == '.') continue;
int xx = x + i - , yy = y + j - ;
if(xx < || xx > r || yy < || yy > c) continue;
ll p = (xx - ) * c + yy;
change[pos] += (1LL << p);
}
}
}
void dfs(int pos){
if(pos > r * c) return;
int x = pos / c, y = pos % c;
if(x >= ){
for(int i = ; i <= c; i++){
int pos2 = (x - ) * c + i;
if(!(lit & (1LL << pos2))) return;
}
}
lit ^= change[pos];
vis[x][y] = ;
step[cnt++] = pos;
if(lit == OK){
if(cnt < ansCnt){
for(int i = ; i < cnt; i++)
ansStep[i] = step[i];
ansCnt = cnt;
lit ^= change[pos];
vis[x][y] = ;
cnt--;
return;
}
}
dfs(pos + );
lit ^= change[pos];
vis[x][y] = ;
cnt--;
dfs(pos + );
}
int main(){
int ca = ;
while(~scanf("%d%d", &r, &c) && r + c){
OK = ;
for(int i = ; i <= ; i++) scanf("%s", s[i] + );
for(int i = ; i <= r; i++){
for(int j = ; j <= c; j++){
init(i, j);
OK += (1LL << ((i - ) * c + j));
}
}
ansCnt = ;
memset(vis, , sizeof(vis));
dfs();
printf("Case #%d\n", ca++);
if(ansCnt == ) printf("Impossible.\n");
else{
for(int i = ; i < ansCnt; i++){
if(i != ) printf(" ");
printf("%d", ansStep[i]);
}
printf("\n");
}
}
return ;
}
UVA 10318 Security Panel(DFS剪枝 + 状压 + 思维)题解的更多相关文章
- Codeforces 293B Distinct Paths DFS+剪枝+状压
目录 题面 题目链接 题意翻译 输入输出样例 输入样例#1 输出样例#1 输入样例#2 输出样例#2 输入样例#3 输出样例#3 输入样例#4 输出样例#4 说明 思路 AC代码 总结 题面 题目链接 ...
- UVa 10318 Security Panel
题意:给你一个3*3的翻转模版,深色部分表示翻转,浅色部分不变.然后你可以在r*c的矩形里依照模版进行翻转,要求所有点亮所有块.输出最小的步骤. 思路:有一点比较好想.每个块至多被翻转一次,翻两次的效 ...
- UVA 1412 Fund Management (预处理+状压dp)
状压dp,每个状态可以表示为一个n元组,且上限为8,可以用一个九进制来表示状态.但是这样做用数组开不下,用map离散会T. 而实际上很多九进制数很多都是用不上的.因此类似uva 1601 Mornin ...
- 【UVa】Headmaster's Headache(状压dp)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- Coco dfs 或者 状压dp。...
C -- Coco Time Limit:1s Memory Limit:64MByte Submissions:148Solved:85 DESCRIPTION Coco just learned ...
- 【UVA】11825 Hackers' Crackdown(状压dp)
题目 传送门:QWQ 分析 $ n<= 16 $ 显然是状压 然后搞一搞(靠着蓝书yy一下) 代码 #include <bits/stdc++.h> using namespace ...
- 2018.8.1 状压 CF482C 题解
noip2016考了一道状压dp,一道期望dp 然而这题是状压期望dp... 所以难度是什么,省选noi吗... 怎么办... 题目大意: 给定n个字符串,甲从中任选出一个串(即选出每个串的概率相同为 ...
- Allowed Letters CodeForces - 1009G(状压思维)
题意: 给出一个字符串 给出几个定点必须是哪个字母(或者是几个字母中的一个) 然后求在满足所有定点后的最小字符串 解析: 没错 这题是暴力 用状压暴力 “a - f” 用”0 - 5“ 这几个数字代 ...
- UVa 208 消防车(dfs+剪枝)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- idea创建java的web项目
2. 3. 4. 5. 6. 步骤八: 点击那个倒立的三角形,然后点击Edit Configurations; 步骤八: 步骤九:配置tocat服务器 步骤十:哎,发现,我怎么就只有一个选项呀,art ...
- java中的锁之AbstractQueuedSynchronizer源码分析(一)
一.AbstractQueuedSynchronizer类介绍. 该抽象类有两个内部类,分别是静态不可继承的Node类和公有的ConditionObject类.AbstractQueuedSynchr ...
- django admim后台不转义提交的html
autoescape¶ Controls the current auto-escaping behavior. This tag takes either on or off as an argum ...
- VMWare虚拟机 window文件传递
无论是将虚拟机的文件传到window上或者是将window上文件传到虚拟机上: 都可以选中文件,然后拖动文件到另一个系统上 提前:虚拟机安装了VMWARE Tools 1)window上文件拖到虚拟机 ...
- python 将字节写入文本文件
想在文本模式打开的文件中写入原始的字节数据 将字节数据直接写入文件的缓冲区即可 >>> import sys >>> sys.stdout.write(b'Hell ...
- numpy文件操作
import numpy as np print '读取csv文件做为数组' arr = np.loadtxt('array_ex.txt', delimiter = ',') print arr i ...
- 转:【专题八】P2P编程
引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...
- rgferg
dfgsdfg fdvgdsafg fgdfgdfg
- poj1185 [NOI2001炮兵阵地]
题目链接 状压DP 本来如果考虑所有情况应该开hh[n][2^10][2^10]表示i行在i-1的状态为j,i-2的状态为k的最大个数 但是由于每行中的人互相限制所以在m=10时只有60种情况 空间就 ...
- vue 去掉路由中的#
在router.js中修改, const router = new VueRouter({ mode: 'history', routes: [...] })