Sicily 1153: 马的周游问题(DFS+剪枝)
Posted Vincent_Bryan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sicily 1153: 马的周游问题(DFS+剪枝)相关的知识,希望对你有一定的参考价值。
这道题没有找到一条回路,所以不能跟1152一样用数组储存后输出。我采用的方法是DFS加剪枝,直接DFS搜索会超时,优化的方法是在搜索是优先走出度小的路径,比如move1和move2都可以走,但是如走了move1后下一步有7种方向可以走,而走了move2后有2种方向可以走,那我们就优先走move2,具体实现参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int _move[8][2] ={{1, -2}, {2, -1}, {2, 1}, {1, 2},{-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}}; 4 5 6 struct Node{ 7 int x, y; 8 vector<int>path; 9 }; 10 Node node; 11 struct Move{ 12 int x, y; 13 int degree; 14 }; 15 16 void getDegree(Move &move){ 17 int ans = 0; 18 int cur_x = node.x+ move.x;//下一步的位置 19 int cur_y = node.y + move.y; 20 21 for(int i = 0; i < 8; i++){//以cur_x, cur_y为起点,检查其出度 22 23 int x = cur_x + _move[i][0]; 24 int y = cur_y + _move[i][1]; 25 if(0 <= x && x < 8 && 0 <= y && y < 8){//如果坐标没有越界并且没有重复走过,则出度加一 26 int flag = 1; 27 for(int j = 0; j < node.path.size(); j++){ 28 if(node.path[j] == x*8 + y){ 29 flag = 0; 30 break; 31 } 32 } 33 34 if(flag)ans++; 35 } 36 37 } 38 move.degree = ans; 39 } 40 41 bool cmp(Move m1, Move m2){ 42 return m1.degree < m2.degree; 43 } 44 bool dfs(int x, int y){ 45 46 node.x = x; 47 node.y = y; 48 Move move[8]; 49 for(int i = 0; i < 8; i++){ 50 move[i].x = _move[i][0]; 51 move[i].y = _move[i][1]; 52 if(0 <= node.x + _move[i][0] && node.x + _move[i][0] < 8 && 53 0 <= node.y + _move[i][1] && node.y + _move[i][1] < 8) 54 getDegree(move[i]); //如果下一步没有越界,则获取它的出度 55 else move[i].degree = 100; //若下一步越界,出度设为100 56 } 57 sort(move, move+8, cmp);//对出度从小到大排序 58 for(int i = 0; i < 8; i++){ 59 if(move[i].degree == 100) continue;//若出度为100,跳过 60 int x = node.x + move[i].x;//下一步位置 61 int y = node.y + move[i].y; 62 if(0 <= x && x < 8 && 0 <= y && y < 8){ 63 int flag = 1; 64 for(int j = 0; j < node.path.size(); j++){ 65 if(node.path[j] == x*8 + y){ 66 flag = 0; 67 break; 68 } 69 } 70 if(flag){ 71 node.path.push_back(x*8 + y);//走下一步 72 73 if(node.path.size() >= 64){//当path的size等于64,则说明已经走遍 74 for(int i = 0; i < node.path.size(); i++){ 75 cout << node.path[i] + 1 << \' \'; 76 } 77 cout << endl; 78 return true; 79 } 80 if(dfs(x, y))return true; 81 node.path.pop_back();//还原到原来 82 node.x -= move[i].x; 83 node.y -= move[i].y; 84 } 85 } 86 87 } 88 return false; 89 } 90 91 int main(){ 92 int n; 93 while(cin >> n && n != -1){ 94 node.path.clear(); 95 n = n-1; 96 int a = n / 8; 97 int b = n % 8; 98 node.path.push_back(a*8 + b); 99 dfs(a, b); 100 } 101 }
以上是关于Sicily 1153: 马的周游问题(DFS+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章