UVa 1343 The Rotation Game (状态空间搜索 && IDA*)
题意:有个#字型的棋盘,2行2列,一共24个格。

如图:每个格子是1或2或3,一共8个1,8个2,8个3.
有A~H一共8种合法操作,比如A代表把A这一列向上移动一个,最上面的格会补到最下面。
求:使中心8个格子数字一致的最少步骤,要输出具体的操作步骤及最终中心区域的数字。如果有多个解,输出字典序最小的操作步骤。
分析 : 还是状态空间的搜索,对象就是一个数字序列,判断中心位置是否一样,可以看出如果使用BFS,每一层还是爆炸,所以使用IDA*,关键还是模拟操作和h函数,这里的h函数是这样定义的,可以看出每一次操作,最多给当前局面添加一个符合要求的数字,那就统计一下中心区域最多的相同数字有多少,然后如果8-h > max_depth - cur_depth的话代表最好的情况下都无法解决,剪枝。模拟操作应该就是很白痴的数组转移赋值了,代码很长,很烦,建议看看刘汝佳的代码。
#include<bits/stdc++.h>
using namespace std;
];
int ans_num;
];
bool Is_ok(int *arr)
{
];
] || temp!=arr[] || temp!=arr[] || temp!=arr[] || temp!=arr[] || temp!=arr[] || temp!=arr[])
return false;
return true;
}
inline int h(const int *now)
{
];
memset(cnt, , sizeof(cnt));
cnt[now[]]++, cnt[now[]]++, cnt[now[]]++,
cnt[now[]]++, cnt[now[]]++, cnt[now[]]++,
cnt[now[]]++, cnt[now[]]++;
], cnt[]);
ret = max(ret, cnt[]);
return ret;
}
inline void Change(int *tmp, int one, int two, int three, int four, int five, int six, int seven)
{
];
index[] = one, index[] = two, index[] = three,
index[] = four, index[] = five, index[] = six;
index[] = seven;
int temp = tmp[one];//!
; i<; i++)
tmp[index[i]] = tmp[index[i+]];
tmp[index[]] = temp;
}
bool DFS(int *now, int cur_depth, int max_depth, int per_dir)
{
- h(now) > max_depth - cur_depth) return false;
if(cur_depth >= max_depth) return false;//!?
; dir<=; dir++){//!
];
){
&&dir==) || (dir==&&per_dir==)) continue;
&&dir==) || (dir==&&per_dir==)) continue;
&&dir==) || (dir==&&per_dir==)) continue;
&&dir==) || (dir==&&per_dir==)) continue;
}
; i<; i++) tmp[i] = now[i];
int top = cur_depth;
switch(dir){
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
: ans[top]=,,,,,,);break;
}
if(Is_ok(tmp)){
ans[top+] = '\0';
ans_num = tmp[];
return true;
}
, max_depth, dir)) return true;
}
return false;
}
int main(void)
{
]) && Init[]){
; i<=; i++){
scanf("%d", &Init[i]);
}
if(Is_ok(Init)){
puts("No moves needed");
printf(]);
continue;
}
;
){
, max_depth, )) break;
max_depth++;
}
puts(ans);
printf("%d\n", ans_num);
}
;
}
刘汝佳代码:
// UVa1343 The Rotation Game
// Rujia Liu
// This solutions uses IDA* instead of BFS described in the book, because it's shorter 8-)
// It's shorter because no need for lookup tables and "automatically" lexicographically smallest solution.
#include<cstdio>
#include<algorithm>
using namespace std;
/*
00 01
02 03
04 05 06 07 08 09 10
11 12
13 14 15 16 17 18 19
20 21
22 23
*/
// lines E~H are computed with the help of rev[]
][]={
{ , , ,,,,}, // A
{ , , ,,,,}, // B
{, , , , , , }, // C
{,,,,,,}, // D
};
] = {, , , , , , , }; // reverse lines of each line
// center squares
] = {, , , , , , , };
];
];
bool is_final() {
; i < ; i++)
]]) return false;
return true;
}
int diff(int target) {
;
; i < ; i++)
if(a[center[i]] != target) ans++;
return ans;
}
inline int h() {
), diff()), diff());
}
inline void move(int i) {
]];
; j < ; j++) a[line[i][j]] = a[line[i][j+]];
a[line[i][]] = tmp;
}
bool dfs(int d, int maxd) {
if(is_final()) {
ans[d] = '\0';
printf("%s\n", ans);
return true;
}
if(d + h() > maxd) return false;
; i < ; i++) {
ans[d] = 'A' + i;
move(i);
, maxd)) return true;
move(rev[i]);
}
return false;
}
int main() {
; i < ; i++)
; j < ; j++) line[i][j] = line[rev[i]][-j];
]) == && a[]) {
; i < ; i++) scanf("%d", &a[i]);
; i < ; i++) ;
if(is_final()) {
printf("No moves needed\n");
} else {
; ; maxd++)
, maxd)) break;
}
printf(]);
}
;
}
瞎:遇到这种看起来很烦的题目,还是没有那种敏感性去试想状态空间搜索,一来就是想着如何模拟,然后脑袋一团shit,思路根本没有,所以总结应该很重要了,提供了一个思考的方向在那里,真正应该思考的是如何去实现这道题所对应的模型,而不是乱想。
UVa 1343 The Rotation Game (状态空间搜索 && IDA*)的更多相关文章
- UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]
解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...
- UVA - 1343 The Rotation Game (BFS/IDA*)
题目链接 紫书例题. 首先附上我第一次bfs+剪枝TLE的版本: #include<bits/stdc++.h> using namespace std; typedef long lon ...
- UVA 1343 The Rotation Game
题意: 给出图,往A-H方向旋转,使中间8个格子数字相同.要求旋转次数最少,操作序列字典序尽量小. 分析: 用一维数组存24个方格.二维数组代表每个方向对应的7个方格.IDA*剪枝是当8-8个方格中重 ...
- UVa 11212 Editing a Book (IDA* && 状态空间搜索)
题意:你有一篇n(2≤n≤9)个自然段组成的文章,希望将它们排列成1,2,…,n.可以用Ctrl+X(剪切)和Ctrl+V(粘贴)快捷键来完成任务.每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴.注 ...
- UVa 1343 旋转游戏(dfs+IDA*)
https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用ID ...
- UVA - 10118Free Candies(记忆化搜索)
题目:UVA - 10118Free Candies(记忆化搜索) 题目大意:给你四堆糖果,每一个糖果都有颜色.每次你都仅仅能拿随意一堆最上面的糖果,放到自己的篮子里.假设有两个糖果颜色同样的话,就行 ...
- 7-10Editing aBook uva11212(迭代加深搜索 IDA*)
题意: 给出n( 2<=n<=9) 个乱序的数组 要求拍成升序 每次 剪切一段加上粘贴一段算一次 拍成1 2 3 4 ...n即可 求排序次数 典型的状态空间搜索问题 ...
- 埃及分数 迭代加深搜索 IDA*
迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...
- UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)
题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...
随机推荐
- 红帽学习记录[RHCE] ISCSI远程块储存
目录 iSCSI 定义 组件术语 启动器 目标 ACL 发现 IQN 登录 LUN 节点 门户 TPG 搭建一个iSCSI服务 提供一个iSCSI目标 配置iSCSI客户端 iSCSI 定义 SCSI ...
- 【Linux 网络编程】OSI七层模型
OSI(Open System Interconnection)开放系统互联模型(1)应用层: 应用层与应用程序界面沟通,以达到展示给用户的目的.(2)表示层: 表示层对网络传输的数据进行交换,使得多 ...
- [转帖]小米手环采用RISC-V 指令集芯片
小米手环4或用“黄山一号”芯片,雷军再回前线,未来走向如何 静心科技 06-1111:19 忘记来源地址了 不过国内的很多东西都是有中国特色的 比如飞腾 比如麒麟(银河麒麟 还有华为的麒麟 980) ...
- Luogu P2572 序列操作
(是道线段树好题√) 题目链接 题外话:这道题我也不知道卡了自己多少天,从初赛之前就开始做,一直到现在才a掉(时间跨度得有将近十天了吧?) 线段树,嗯,好像很简单的样子. 但事实上因为自己太菜了,卡了 ...
- Git-版本控制 (二)
昨天我们成功安装了Git,并且成功配置了环境变量~如果想看之前步骤的童鞋,请戳这里Git-版本控制(一) 今天我们要做的事情是:创建版本库. (觉得非高大尚的童鞋举个爪子 = . =) en~~~~ ...
- 云服务器linux重新挂载指定目录(非扩充)
新买的香港云服务器,系统只能在商家的控制台上安装. 系统和硬盘分开的,根目录空间只有10G.需要重新设置相关目录的大小,如:/usr./var./home等. 以下是自己的解决方法小计. 一.初始的分 ...
- 剑指offer-二进制中1的个数-进制转化-补码反码原码-python
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. ''' 首先判断n是不是负数,当n为负数的时候,直接用后面的while循环会导致死循环,因为负数 向左移位的话最高位补1 ...
- ExpressionToSQL
ExpressionToSql using System; using System.Collections.Generic; using System.Collections.ObjectModel ...
- sublime text 3 环境设置
1. 设置build system 环境 tool -> build system -> new build system ,粘贴以下代码并保存 { "cmd":[&q ...
- 在springboot中使用拦截器
在springMVC中可以实现拦截器,是通过实现HandlerInterceptor接口,然后在springmvc-web.xml中配置就可以使用拦截器了.在springboot中拦截器也是一样的思想 ...