gym100206E (n*n)的马遍历问题 贪心
来源:互联网 发布:马赛克软件下载 编辑:程序博客网 时间:2024/06/06 01:34
其实马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选择‘出口’最小的进行搜索,‘出口’的意思是在这些子结点中它们的可行子结点的个数,也就是‘孙子’结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点(顾名思义就是没有出口又没有跳过的结点),这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。这种算法称为为贪心算法,也叫贪婪算法或启发式算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪心策略,至于什么问题需要什么样的贪心策略是不确定的,具体问题具体分析。实验可以证明马遍历问题在运用到了上面的贪心策略之后求解速率有非常明显的提高,如果只要求出一个解甚至不用回溯就可以完成,因为在这个算法提出的时候世界上还没有计算机,这种方法完全可以用手工求出解来,其效率可想而知。
这道题的起点不是固定的,原来只把(1,1)当起点,结果wa了好几发。只好先暴力计算起点的最大值(x<=8,y<=6)。
#include<bits/stdc++.h>const int INF = 0x3f3f3f3f;const int Maxn = 255;#define ll long long#define mem(x,y) memset(x,y,sizeof(x))using namespace std;int mp[Maxn][Maxn], cnt = 0, flag = 0;int mx[8] = {2, 2, 1, 1, -2, -2, -1, -1}, my[8] = {1, -1, 2, -2, 1, -1, 2, -2};int door(int x, int y, int n) { // 计算(x,y)下一步能跳的位置数 int cnt = 0; for (int i = 0; i < 8; i++) { int a = x + mx[i], b = y + my[i]; if (a >= 1 && a <= n && b >= 1 && b <= n && mp[a][b] == 0) cnt++; } return cnt;}int MM = 0, NN = 0;void deal(int n) { if (n > 1 && n < 5) return; cnt = flag = 0; for (int tt = 1; tt <= 8; tt++) for (int xx = 1; xx <= 6; xx++) { int x = tt, y = xx; mem(mp, 0); for (cnt = 1; cnt <= n * n; cnt++) { mp[x][y] = cnt; if (cnt == n * n) { flag = 1; return; } if (door(x, y, n) == 0) break; int m = 10, a, b; for (int i = 0; i < 8; i++) { // 贪心 int p = x + mx[i], q = y + my[i]; if (!(p >= 1 && p <= n && q >= 1 && q <= n && mp[p][q] == 0)) continue; int k = door(p, q, n); if (k < m) { m = k; a = p, b = q; } } x = a, y = b; } }}int main() { freopen("classic.in", "r", stdin); freopen("classic.out", "w", stdout); int N; while (cin >> N) { deal(N); if (flag == 0) printf("No solution.\n"); else { printf("There is solution:\n"); for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) printf("%d%c", mp[i][j], j == N ? '\n' : ' '); } }}
阅读全文
0 0
- gym100206E (n*n)的马遍历问题 贪心
- 回溯法:输出n的全排列,解哈密顿问题,马的遍历问题,解八后问题
- Java的n++问题
- N皇后的问题
- fork() /n的问题
- selenium3.n的问题
- 可怕的N!问题
- Hibernate的1+N问题(N+1)
- \r,\n,\r\n的问题分析
- 关于java的n=n++问题
- N*N皇后问题
- hdu1061-N*N问题
- (n++)+(n++)+(n++)与(++n)+(++n)+(++n)的区别
- n个人用m个水龙头的接水问题 贪心
- struts2 遍历Map的N中方法
- 遍历json数据的n种方法
- 二叉树遍历的N种实现
- N!问题
- webdriver定位元素的方法和基础函数的使用
- 模拟基于ajax调后台接口的json数据
- python基础学习(3)
- POJ2153
- eclipse启动了tomcat,浏览器可以访问tomcat下的项目但不能访问tomcat主页
- gym100206E (n*n)的马遍历问题 贪心
- mysql入门(外连接十)
- Pandas Index 属性
- Redis常用操作命令
- 使用node-inspector调试NodeJS代码
- Linux下VI的基本操作实验
- 必须掌握的技术知识点
- struts2 中redirectAction如何传递参数!
- Problems when installing R and Rstudio in Ubuntu: