ZOJ 3755 Mines 回溯+剪枝
2014-07-16 22:02
603 查看
Mines
Time Limit: 2 Seconds Memory Limit: 65536 KB
As a small-game fan, Flandre loves playing the Mine-sweeping very much. He spends 23 hours playing the lowest level of Mine-sweeping every day.
One day, when Flandre is playing Mine-sweeping, a strange idea comes to him:
"Can I just calculate the minimum number of the mine in current state of the game ?"
To simplify this problem, we suppose the map is a N*(M*2+1) matrix
and there are some mines in the grids of odd columns. You have got all the messages about the even columns which are represented as a N * M number
matrix.
For example: N = 3, M = 2(# represent the mines, number means how many mines around it)
# 2 1 2 #
2 4 # 3 0
# 3 # 2 0
the messages about the even columns are:
2 2
4 3
3 2
Your task is to calculate the minimum number of mines with the messages matrix.
The first line contains two integers N(1≤ N≤ 10), M(1≤ M≤ 10)
Then followed by N lines, each line contain M integers represent the messages matrix.
Process to the end of input.
Time Limit: 2 Seconds Memory Limit: 65536 KB
As a small-game fan, Flandre loves playing the Mine-sweeping very much. He spends 23 hours playing the lowest level of Mine-sweeping every day.
One day, when Flandre is playing Mine-sweeping, a strange idea comes to him:
"Can I just calculate the minimum number of the mine in current state of the game ?"
To simplify this problem, we suppose the map is a N*(M*2+1) matrix
and there are some mines in the grids of odd columns. You have got all the messages about the even columns which are represented as a N * M number
matrix.
For example: N = 3, M = 2(# represent the mines, number means how many mines around it)
# 2 1 2 #
2 4 # 3 0
# 3 # 2 0
the messages about the even columns are:
2 2
4 3
3 2
Your task is to calculate the minimum number of mines with the messages matrix.
Input
There are multiple test cases. For each test case:The first line contains two integers N(1≤ N≤ 10), M(1≤ M≤ 10)
Then followed by N lines, each line contain M integers represent the messages matrix.
Process to the end of input.
Output
For each the case, print the minimum number of mines.Sample Input
3 2 2 2 4 3 3 2
Sample Output
4
解题思路:1.本人小菜,直接建图回溯……
2.大神,状态压缩dp做的……
/******************************** * 作者:Linfly * 时间:2014-07-16 12:26 ********************************/ #include <iostream> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <stack> #include <cstring> using namespace std; #define MAXN 50 int m[MAXN][MAXN]; int N,M; int result; int dx[6]={-1, 0, 1,-1,0,1}; int dy[6]={-1,-1,-1, 1,1,1}; int CalMines(int x, int y) { int num = 0; for (int i = 0; i<6; i++) { num += m[x + dx[i]][y + dy[i]]; } return -num; } void Search(int currpos, int currmine) { if (currmine > result) //当前布雷数超过最大雷数 return ; if (currpos == (N+1)*(M*2+1)) //完成布雷 { for (int i = N*(M*2+1)+1; i<(N+1)*(M*2+1); i+=2) //检验最后一行布雷情况 { int x = i/(M*2+1); int y = i%(M*2+1); if (CalMines(x,y) != m[x][y]) return ; } if (currmine < result) result = currmine; return ; } int x = currpos/(M*2+1); //计算当前位置的坐标 int y = currpos%(M*2+1); if (y&1 == 1) //当前位置为周边雷数字 { //cout << "(" << x << "," << y <<")" << CalMines(x,y)<< ")" ; if (CalMines(x,y) > m[x][y]) //当前位置数的周边雷多了 return ; /* cout << "+++++++++++++++++++ " << currpos << endl; for (int i = 0; i<N+2; i++) { for (int j = 0; j<=M*2; j++) { cout << m[i][j]; } cout << endl; } cout << "++++++++++++++++++++++++++++++" << endl; */ Search(currpos+1, currmine); //搜索下一个位置 } else { if (y>0&&x>1 && CalMines(x-1,y-1) == m[x-1][y-1]) //左上角 { Search(currpos+1, currmine); } else if(y>0&&x>1 && CalMines(x-1,y-1) == m[x-1][y-1]-1) { m[x][y] = -1; Search(currpos+1, currmine+1); m[x][y] = 0; } else if (y>0&&x>1) { return ; } else { m[x][y] = -1; Search(currpos+1, currmine+1); m[x][y] = 0; Search(currpos+1, currmine); } } } int main() { while (cin >> N >> M) { result = 0xfffffff; memset(m, 0, sizeof(m)); for (int i = 1; i<=N; i++) { for (int j = 0; j<M; j++) { cin >> m[i][j*2+1]; } } /* for (int i = 0; i<N+2; i++) { for (int j = 0; j<=M*2; j++) { cout << m[i][j]; } cout << endl; }*/ Search(M*2+1, 0); cout << result << endl; } return 0; }
</pre>
相关文章推荐
- ZOJ 3755 Mines
- 【ZOJ】3233 Lucky Number
- ZOJ-1455
- ZOJ 3885 The Exchange of Items
- ZOJ 1453 Surround the Trees(求凸包周长 刘汝佳模板)
- ZOJ 3210 A Stack or A Queue
- ZOJ-1954
- ZOJ 3885 The Exchange of Items
- 【DBSDFZOJ 4370】小宁的机器人(模拟)
- zoj 2671 Cryptography(矩阵+线段树)
- zoj Fibonacci Numbers ( java , 简单 ,大数)
- 【ZOJ】3881 From the ABC conjecture【暴力容斥】
- zoj 2112 (主席树,树状数组套线段树)
- ZOJ 2969 Easy Task
- ZOJ-1589
- zoj 2770 Burn the Linked Camp 差分约束系统
- zoj 1884 简单 键盘 字符 处理
- ZOJ 3612 Median(SBT)
- ZOJ 1151 Word Reversal
- zoj 3549 (模运算)