1. 题目描述
有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列。

2. 基本思路
24个数据,8种移动方式,数据量很小了,所以基本怎么玩儿都可以。
需要注意的是因为横线竖线间有交点,所以每个条带的数据可能都是变化的。
采用IDA*算法可解。
所谓IDA*,就是不断对所求操作需要长度进行增加,然后不断当前长度是否存在可行的操作序列。
判断是否存在可行操作序列的方法是深搜,这里需要注意去除先移动A紧接着移动F的类似情况。
H函数的基本想法很简单,即判断中心8个字符的最少改变几个就可以满足条件。

3. 代码

 /* 1667 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int INF = 0x3f3f3f3f;
const int maxl = ;
int op[maxl];
int a[];
int pos[][] = {
{, , , , , , },
{, , , , , , },
{, , , , , , },
{, , , , , , }
};
int eight[] = {
, , , , , , ,
};
int mirror[] = {
, , , , , , ,
};
bool flag;
int v; void Init() {
rep(i, , ) {
int j = mirror[i];
memcpy(pos[j], pos[i], sizeof(pos[j]));
reverse(pos[j], pos[j]+);
}
} void Rotate(int *a, int d) {
int tmp = a[pos[d][]];
rep(i, , )
a[pos[d][i-]] = a[pos[d][i]];
a[pos[d][]] = tmp;
} int H(int *a) {
int c[]; c[] = c[] = c[] = ;
rep(i, , )
++c[a[eight[i]]]; return - max(c[], max(c[], c[]));
} void dfs(int *a, int dep, int fa) {
int mn = H(a); if (dep < mn)
return ; if (dep == ) {
if (mn == ) {
flag = true;
v = a[eight[]];
}
return ;
} int b[]; rep(i, , ) {
if (mirror[i] == fa)
continue;
op[dep] = i;
memcpy(b, a, sizeof(b));
Rotate(b, i);
dfs(b, dep-, i);
if (flag) return ;
}
} void solve() {
int mn = H(a); if (mn == ) {
printf("No moves needed\n%d\n", a[eight[]]);
return ;
} flag = false;
for (int l=mn; ; ++l) {
dfs(a, l, -);
if (flag) {
per(i, , l+) {
putchar('A'+op[i]);
}
printf("\n%d\n", v);
break;
}
}
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif Init();
while (scanf("%d", &a[])!=EOF && a[]) {
rep(i, , )
scanf("%d", &a[i]);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

4. 数据生成器。

/*
2 3 2 2 1 1 3 1 3 2 2 1 2 2 2 3 3 2 3 1 2 2 2 2
2 3 2 1 2 1 1 2 1 2 2 3 2 2 2 2 2 2 1 3 3 2 2 2
1 1 3 1 3 3 1 3 3 3 1 3 2 1 2 2 1 3 3 3 1 3 3 3
1 2 1 1 1 2 1 2 1 3 1 2 1 2 2 1 1 1 1 1 2 1 3 1
3 2 3 3 3 2 3 3 1 2 3 3 3 1 3 1 2 1 3 3 2 3 2 3
2 2 3 2 3 3 2 1 3 2 2 3 1 2 2 2 2 2 1 2 1 2 3 2
3 2 1 1 3 3 3 1 2 3 3 3 2 3 1 3 3 3 3 3 1 1 3 3
3 2 3 3 3 2 2 1 1 3 1 3 3 3 2 3 3 3 1 3 3 3 3 2
1 3 2 1 1 3 1 1 1 3 3 1 1 1 3 3 3 2 1 1 2 1 1 2
1 1 3 3 2 3 1 3 2 3 2 1 3 1 2 2 2 1 1 2 2 2 3 2
0
*/ /*
AABDDHA
2
BFFF
2
BBGGH
3
AGHBH
1
GBGF
3
ABBHHF
2
BCCEC
3
BHA
3
EGG
1
ADHBBH
2
*/
 from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 10
bound = 10**5
# fout.write("%d\n" % (t))
for tt in xrange(t):
n1 = randint(10, 15)
token = randint(1, 3)
L = [token for i in xrange(n1)]
op = range(1, 4)
op.remove(token)
for i in xrange(24-n1):
idx = randint(0, 1)
x = op[idx]
L.append(x)
shuffle(L)
fout.write(" ".join(map(str, L)) + "\n")
fout.write("0\n") def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()

【HDOJ】1667 The Rotation Game的更多相关文章

  1. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  2. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  3. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  4. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

  5. 【HDOJ】【2829】Lawrence

    DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...

  6. 【HDOJ】【3415】Max Sum of Max-K-sub-sequence

    DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...

  7. 【HDOJ】【3530】Subsequence

    DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...

  8. 【HDOJ】【3068】最长回文

    Manacher算法 Manacher模板题…… //HDOJ 3068 #include<cstdio> #include<cstring> #include<cstd ...

  9. 【HDOJ】【1512】Monkey King

    数据结构/可并堆 啊……换换脑子就看了看数据结构……看了一下左偏树和斜堆,鉴于左偏树不像斜堆可能退化就写了个左偏树. 左偏树介绍:http://www.cnblogs.com/crazyac/arti ...

随机推荐

  1. linux下挂载移动硬盘ntfs格式

    http://jingyan.baidu.com/article/f96699bba93dce894e3c1bec.html fdisk -l安装后 使用命令mount -t ntfs-3g /dev ...

  2. listView异步处理图片下载缓存

    package cn.wangmeng.test; import java.io.File;import java.io.FileOutputStream;import java.io.IOExcep ...

  3. delphi中的临界区

    var fLock:TRTLCriticalSection; //定义临界区域 // 初始化 InitializeCriticalSection(fLock); //进入临界区 EnterCritic ...

  4. Demo学习: ClientInfo

    ClientInfo 获取客户端环境参数,从0.9版本开始新增了TUniClientInfoRec对象,可以得到客户端的一些信息,之前为了获取浏览器版本号需要自己写函数,现在可以直接使用TUniCli ...

  5. html lang

    目前,语言的标签表示法的国际标准是RFC 4646,名称是<Tags for Identifying Languages>.简单说,这个文件规定,一种语言的标签应该按照如下方式排列: la ...

  6. SVN备份教程(一)

    最近一段时间在项目中用到了SVN备份的相关内容,这里给大家做一个简单的教程,重点在于SVN备份环境的搭建过程中,大家学到的解决问题的思维方式. 1.分类 SVN备份主要分为两种:一种是远程备份,另一种 ...

  7. MyBatis定义复合主键

    <resultMap type="XX" id="XXMap">   <id property="id" column=& ...

  8. [转]popwindow用法

    [转]弹出窗口的两种实现方式 PopupWindow 和 Activity  链接:http://www.cnblogs.com/winxiang/archive/2012/11/20/2778729 ...

  9. C#的历史及IDE总结

         原Borland公司的首席研发设计师安德斯·海爾斯伯格(Anders Hejlsberg)在微軟開發了Visual J++ 1.0,很快的Visual J++由1.1版本升級到6.0版.SU ...

  10. [DP] 堆盒子问题

    给一堆盒子,知道每个盒子的三围(长宽高),盒子正面朝你,不能旋转摆放,按照大的放在小的下面的原则堆起来,必须是 strictly larger,同样大小的盒子不行,问怎么样堆到最大的高度? 思路:动态 ...