标签:acm
ACM
题目地址:UVA 10318 - Security Panel
题意:
这题跟点灯的题目很像,点灯游戏选择一盏灯时会让它以及四周的灯改变状态。
但是我们有特殊的开开关技巧,它给出了改变状态的位置,而不是四周都改变。
问你从全部关着变成全部开着的最小开关步骤。
分析:
很明显,在一个位置上点两次或更多次是没有必要的,所以一个位置只有选择与不选择,用dfs即可,但如果暴力所有可能,复杂度是2^25,会超时,所以要剪枝。
由于影响范围是3*3的,所以开关是无法影响两行前的状态的,只要在要走向下一行前判断下就行了。
由于数据量很小,这个剪枝足够了。
代码:
/* * Author: illuz <iilluzen[at]gmail.com> * File: 10318.cpp * Create Date: 2014-06-29 19:51:39 * Descripton: */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int dx[] = {-1,-1,-1, 0, 0, 0, 1, 1, 1}; const int dy[] = {-1, 0, 1,-1, 0, 1,-1, 0, 1}; const int N = 6; int r, c, cas; int change[3*3], lit[N][N], prs[N*N], ans[N*N], cnt; char str[4]; bool check(int l1) { if (l1 >= 0) { for (int i = 0; i < c; i++) { if (!lit[l1][i]) { return false; } } } return true; } void pressfunc(int x, int y) { for (int i = 0; i < 9; i++) { if (change[i]) { int tx = x + dx[i], ty = y + dy[i]; if (tx >= 0 && tx < r && ty >= 0 && ty < c) { lit[tx][ty] = !lit[tx][ty]; } } } } void dfs(int x, int y, int press) { if (y == c) { if (x == r - 1) { // check if all light for (int i = 0; i < r; i++) { if (!check(i)) { return; } } // if all light, update the ans if (press < cnt) { cnt = press; for (int i = 0; i < press; i++) { ans[i] = prs[i]; } } return; } else { if (!check(x - 2)) { // if not all light in line x - 2 return; } x++; y = 0; } } // not press dfs(x, y + 1, press); // press pressfunc(x, y); prs[press] = c * x + y + 1; dfs(x, y + 1, press + 1); pressfunc(x, y); // roll back } int main() { while (~scanf("%d%d", &r, &c) && (r || c)) { // input for (int i = 0; i < 3; i++) { scanf("%s", str); for (int j = 0; j < 3; j++) { change[i*3+j] = str[j] == '*' ? 1 : 0; } } // init memset(lit, 0, sizeof(lit)); cnt = r * c + 1; // solve printf("Case #%d\n", ++cas); dfs(0, 0, 0); if (cnt != r * c + 1) { for (int i = 0; i < cnt - 1; i++) { printf("%d ", ans[i]); } printf("%d\n", ans[cnt - 1]); } else { puts("Impossible."); } } return 0; }
UVA 10318 - Security Panel dfs 剪枝,布布扣,bubuko.com
UVA 10318 - Security Panel dfs 剪枝
标签:acm
原文地址:http://blog.csdn.net/hcbbt/article/details/35830907