题目链接:传送门

题目大意:

汉诺塔,给定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. linux command useradd

    Linux command useradd [Purpose]        Learning linux command useradd to create a new user or update ...

  2. 服务消费和负载(Feign)

    Spring Cloud Feign Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单.我们只需要通过创建接口 ...

  3. RabbitMQ进阶使用-延时队列的配置(Spring Boot)

    依赖 MAVEN配置pom.xml <dependency> <groupId>org.springframework.boot</groupId> <art ...

  4. DeepLearning4J

    http://blog.csdn.net/nysyxxg/article/details/52554734

  5. 使用MYSQL数据库实现编程----第二章第三章课堂知识小总结

    第二章1:创建数据库create database myschool 2.数据类型  1.整型 int  2.小数 double  精确度要求高的 ----Decimal(18,4)  2222222 ...

  6. PHP多进程处理并行处理任务实例

    本文目的 本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步.写得比较简单,作为备忘录. PHP多进程 通过pcntl_XXX系列函数使用多进程功能 ...

  7. java的类class 和对象object

    java 语言的源代码是以类为单位存放在文件中,已public修饰的类名须和存放这个类的源文件名一样.而 一个源文件中只能有一个public的类,类名的首字母通常为大写. 使用public修饰的类可以 ...

  8. 1.5 socket服务器传输文件

    socket服务器代码 # -*- coding: utf-8 -*-import sys,os,time,_thread from socket import * host = 'localhost ...

  9. SQL-7查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t (group 与count)

    题目描述 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数tCREATE TABLE `salaries` (`emp_no` int(11) NOT NULL,`salary` int ...

  10. 关于这次安装Oracle

    前后大概经历了一个星期,今天下午(先是用的Navicat)当我尝试性的把用户名上方的复选项从服务名换成SID时,竟然瞬间连接成功了,整个人都是蒙B的,这样就好了? 之后我又用PLsql测试了一下,秒进 ...