题目链接:传送门

题目大意:

汉诺塔,给定n个盘子(n <= 45),起始状态和结束状态,求最小的步数以及路径。

思路:

考虑用dfs贪心地将剩余最大盘归位。

#include<bits/stdc++.h>

using namespace std;
const int MAX_N = ;
const int SUM = ; int N, ans;
int f1[MAX_N], f2[MAX_N]; void dfs(int cur, int st, int ed, bool now)
{
int mid = SUM - st - ed;
if (st == ed) {
if (cur > )
dfs(cur-, f1[cur-], now ? f2[cur-] : ed, now);
return;
}
if (cur > )
dfs(cur-, f1[cur-], mid, false);
ans++;
printf("move %d from %c to %c\n", cur, 'A' + st, 'A' + ed);
f1[cur] = ed;
if (cur > )
dfs(cur-, f1[cur-], now ? f2[cur-] : ed, now);
} void input()
{
ans = ;
cin >> N;
for (int i = ; i < ; i++) {
int x;
cin >> x;
while (x--) {
int cur;
cin >> cur;
if (i/)
f2[cur] = i%;
else
f1[cur] = i%;
}
}
} int main(){
input();
dfs(N, f1[N], f2[N], true);
cout << ans << endl;
return ;
}

以上代码会被这组数据hack。

/*
3
1 3
0
2 2 1
2 2 1
0
1 3
*/

但是大多数情况下贪心思路没有问题,所以用模拟退火优化。

#include<bits/stdc++.h>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX_N = ;
const int SUM = ; int N, ans, icur;
string sans, scur;
int ff1[MAX_N], ff2[MAX_N];
int f1[MAX_N], f2[MAX_N]; void mov(int cur, int st, int ed)
{
icur++;
scur += "move ";
if (cur >= )
scur += char(cur/ + '');
scur += char(cur% + '');
scur += " from ";
scur += char(st + 'A');
scur += " to ";
scur += char(ed + 'A');
scur += "\n";
} void dfs(int cur, int st, int ed, bool now)
{
int mid = SUM - st - ed;
if (st == ed) {
if (cur > )
dfs(cur-, f1[cur-], now ? f2[cur-] : ed, now);
return;
}
if (cur > )
dfs(cur-, f1[cur-], mid, false);
mov(cur, st, ed);
f1[cur] = ed;
if (cur > )
dfs(cur-, f1[cur-], now ? f2[cur-] : ed, now);
} void input()
{
ans = INF;
cin >> N;
for (int i = ; i < ; i++) {
int x;
cin >> x;
while (x--) {
int cur;
cin >> cur;
if (i/)
ff2[cur] = i%;
else
ff1[cur] = i%;
}
}
} int main(){
input();
int T = ;
srand();
while (T--) {
icur = ;
scur = "";
for (int i = ; i <= N; i++) {
f1[i] = ff1[i];
f2[i] = ff2[i];
}
for (int i = N; i >= ; i--) {
if (rand()%(i+) != )
dfs(i, f1[i], f2[i], true);
else
dfs(i, f1[i], SUM-f1[i]-f2[i], true);
}
dfs(N, f1[N], f2[N], true);
if (ans > icur) {
ans = icur;
sans = scur;
}
}
cout << sans << ans << endl;
return ;
}
/*
3
1 3
0
2 2 1
2 2 1
0
1 3
*/

P1242 新汉诺塔(搜索+模拟退火)的更多相关文章

  1. 洛谷P1242 新汉诺塔(dfs,模拟退火)

    洛谷P1242 新汉诺塔 最开始的思路是贪心地将盘子从大到小依次从初始位置移动到目标位置. 方法和基本的汉诺塔问题的方法一样,对于盘子 \(i\) ,将盘子 \(1\to i-1\) 放置到中间柱子上 ...

  2. 洛谷 P1242 新汉诺塔

    原题链接 题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案 ...

  3. 洛谷P1242 新汉诺塔

    传送门啦 首先要将第n个盘子从x到y,那么就要把比n小的盘子全部移到6-x-y,然后将n移到y 仔细想想:6代表的是3根初始柱,3根目标柱. 6-(x+y) 便是我们的中转柱了,因为到这个位置是最优的 ...

  4. 洛谷P1242 新汉诺塔 【神奇的递归】

    题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案,使得从初 ...

  5. P1242 新汉诺塔(hanio)

    这道题加深了hanio的理解 如果我们要移动第n个盘子.那么就是说,n+1以后(包括n+1)的盘子都已经到位了 #include<iostream> #include<cstdio& ...

  6. P1242 新汉诺塔

    题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案,使得从初 ...

  7. 大白_uva10795_新汉诺塔

    题意:给出所有盘子的初态和终态,问最少多少步能从初态走到终态,其余规则和老汉诺塔一样. 思路: 若要把当前最大的盘子m从1移动到3,那么首先必须把剩下的所有盘子1~m-1放到2上,然后把m放到3上. ...

  8. UVA 10795 新汉诺塔问题

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. UVa新汉诺塔问题(A Different Task,Uva 10795)

    主要需要理递归函数计算 #define MAXN 60+10 #include<iostream> using namespace std; int n,k,S[MAXN],F[MAXN] ...

随机推荐

  1. shiro jwt 构建无状态分布式鉴权体系

    一:JWT 1.令牌构造 JWT(json web token)是可在网络上传输的用于声明某种主张的令牌(token),以JSON 对象为载体的轻量级开放标准(RFC 7519). 一个JWT令牌的定 ...

  2. 用mobiscroll.js的treelist实现弹出下拉效果

    首先跟上次说的一样, 第一步:引入js.css样式 1)mobiscroll-2.13.2.full.min.css 2)jquery.min.js 3)mobiscroll-2.13.2.full. ...

  3. 从概率图模型pgm到rbm

    有向图模型:directed acyclic graph  DAG  贝叶斯网络 对称的,无向图, UGM: undirected graphic model  UGM, 更有名的名称是MRF,mar ...

  4. Win10系列:JavaScript图形

    在页面中添加canvas元素会在页面上生成一个矩形的位图画布,可以使用JavaScript在画布上实时绘制图形图像.在绘制图形时,需要先调用画布的getContext函数获取与该画布相关的用于绘制图形 ...

  5. learning scala write to file

    scala 写文件功能: scala> import java.io.PrintWriterimport java.io.PrintWriter scala> val outputFile ...

  6. 二. Python基础(2)--语法

    二. Python基础(2)--语法 1.实现一个简单的登录系统 '''# 形式1 n = 1 while n < 4:     name = input("请输入姓名\n" ...

  7. node(2) EventEmitter类 事件队列 事件和error事件方法

    事件队列的核心:事件触发与事件监听器功能的封装. // 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var e ...

  8. C++基础知识:泛型编程

    1.泛型编程的概念 ---不考虑具体数据类型的编程模式Swap 泛型写法中的 T 不是一个具体的数据类型,而是泛指任意的数据类型. 2.函数模板 - 函数模板其实是一个具有相同行为的函数家族,可用不同 ...

  9. 1.6socket服务器传送文件--gui窗口

    socket服务器代码 import sys,os,time,_thread from socket import * class Server(object): def __init__(self) ...

  10. 基于Nutch Solr等基于搭建一体化的数据抓取平台

    参考链接:https://www.ibm.com/developerworks/cn/opensource/os-cn-BigInsightsNutchSolr/