HDU-4531 吉哥系列故事——乾坤大挪移 模拟
题意:给定一个九宫格,然后能够选择某行或者是某列滚动,每个小方格分为上下左右四个块,每个块可以涂上4种不同的颜色。问最少使用多少步能够使得所有相同颜色相互联通。
分析:由于九宫格的所有的状态只有9!(362880)种,于是想起了先对每个格子进行标号,然后根据逆序对的数量进行一个递增进制数的hash处理,这样bfs搜索就能够去重了,接着只需要判断每个状态是否满足联通即可。这里的判定选择了先统计了不同颜色格子的数量然后dfs搜索,应该并查集也可以搞。滚动使用指针滚动即可,对于不能动的格子该格子所在行和列都不能够滚动。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std; // 9! = 362880
const int LIM = ;
int fac[]; // 递增进制数的权值
int tot[]; // 四种颜色的个数
char vis[LIM]; // hash九宫格
char op[]; // 滚动的操作的限制
char hav[]; // 4*9个格子的标记 struct Block {
char color[];
int id;
}bk[][]; struct Node {
Block *ptr[][];
int key;
int ti;
Node() {}
Node(Block (*x)[]) {
ti = ;
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
ptr[i][j] = &x[i][j];
}
}
getkey();
}
void show() {
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
printf("%5d", ptr[i][j]->id);
}
puts("");
}
puts("");
}
void getkey() {
int cnt;
key = ;
for (int i = ; i < ; ++i) {
cnt = ;
for (int j = i+; j < ; ++j) {
if (ptr[j/][j%]->id < ptr[i/][i%]->id) ++cnt;
}
key += cnt * fac[-i];
}
}
int dfs(int x, int y, int z) {
if (hav[(x*+y)*+z]) return ;
hav[(x*+y)*+z] = ;
char ch = ptr[x][y]->color[z];
int ret = ;
if (z == ) {
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (x > && ptr[x-][y]->color[] == ch) ret += dfs(x-, y, );
} else if (z == ) {
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (x < && ptr[x+][y]->color[] == ch) ret += dfs(x+, y, );
} else if (z == ) {
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (y > && ptr[x][y-]->color[] == ch) ret += dfs(x, y-, );
} else {
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (ptr[x][y]->color[] == ch) ret += dfs(x, y, );
if (y < && ptr[x][y+]->color[] == ch) ret += dfs(x, y+, );
}
return ret;
}
bool judge() {
memset(hav, , sizeof (hav));
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
for (int k = ; k < ; ++k) {
if (!hav[(i*+j)*+k]) {
int cnt = dfs(i, j, k);
switch(ptr[i][j]->color[k]) {
case 'R': if (cnt != tot[]) return false; break;
case 'G': if (cnt != tot[]) return false; break;
case 'B': if (cnt != tot[]) return false; break;
default : if (cnt != tot[]) return false;
}
}
}
}
}
return true;
}
}; void pre() {
fac[] = ;
for (int i = ; i < ; ++i) {
fac[i] = fac[i-] * i;
}
} void swapr(Block *x[], Block *y[], int dir) { // 横向的滚动
if (dir == ) { // 向左
y[] = x[], y[] = x[], y[] = x[];
} else { // 向右
y[] = x[], y[] = x[], y[] = x[];
}
} void swapc(Block *x[], Block *y[], int dir) { // 纵向的滚动
if (dir == ) { // 向上
y[] = x[], y[] = x[], y[] = x[];
} else { // 向下
y[] = x[], y[] = x[], y[] = x[];
}
} int bfs() {
queue<Node>q;
Node tmp = Node(bk);
Node pos;
memset(vis, , sizeof (vis));
q.push(tmp); // 初始化是没有逆序对的
vis[tmp.key] = ;
while (!q.empty()) {
pos = q.front();
q.pop();
if (pos.judge()) {
return pos.ti;
}
for (int i = ; i < ; ++i) {
if (op[i]) continue;
tmp = pos;
if (i < ) { // 横向的滚动
for (int j = ; j < ; ++j) {
swapr(&pos.ptr[i][], &tmp.ptr[i][], j);
tmp.getkey();
tmp.ti = pos.ti + ;
if (!vis[tmp.key]) {
vis[tmp.key] = ;
q.push(tmp);
}
}
} else { // 纵向的
for (int j = ; j < ; ++j) {
swapc(&pos.ptr[][i%], &tmp.ptr[][i%], j);
tmp.getkey();
tmp.ti = pos.ti + ;
if (!vis[tmp.key]) {
vis[tmp.key] = ;
q.push(tmp);
}
}
}
}
}
} int main() {
int T, ca = ;
pre();
scanf("%d", &T);
while (T--) {
memset(op, , sizeof (op));
memset(tot, , sizeof (tot));
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
scanf("%s", bk[i][j].color);
for (int k = ; k < ; ++k) {
switch(bk[i][j].color[k]) {
case 'R': ++tot[]; break;
case 'G': ++tot[]; break;
case 'B': ++tot[]; break;
default : ++tot[];
}
}
bk[i][j].id = i*+j; // 0-8
if (bk[i][j].color[] == '') {
op[i] = op[+j] = ; // 两种操作无法进行
}
}
}
printf("Case #%d: %d\n", ++ca, bfs());
}
return ;
}
HDU-4531 吉哥系列故事——乾坤大挪移 模拟的更多相关文章
- hdu 4512 吉哥系列故事——完美队形I【LCIS经典应用】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4512 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- HDU 4513 吉哥系列故事――完美队形II(Manacher)
题目链接:cid=70325#problem/V">[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher V - 吉哥系列故事――完美队形I ...
- HDU 4513 吉哥系列故事――完美队形II
http://acm.hdu.edu.cn/showproblem.php?pid=4513 吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others) ...
- HDU 4513 吉哥系列故事——完美队形II manacher
吉哥系列故事——完美队形II Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希 ...
- hdu 4513 吉哥系列故事——完美队形II (manachar算法)
吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) P ...
- HDU 4512——吉哥系列故事——完美队形I——————【LCIS应用】
吉哥系列故事——完美队形I Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- HDU 4513 吉哥系列故事——完美队形II(Manacher)
Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成 ...
- HDU 4512 吉哥系列故事——完美队形(LCIS)
Problem Description 吉哥这几天对队形比较感兴趣. 有一天,有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一 ...
- hdu 4502吉哥系列故事——临时工计划 (简单DP)
Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只 ...
随机推荐
- JavaMail邮件开发
一.只带有纯文本的邮件 代码事例如下: package com.lyh.sendemail; import java.util.Properties; import javax.mail.Messag ...
- 当div自适应的高度超过预设的高度的时候出现滚动条的办法
方法一:主要是 min-height:50px; max-height:200px;overflow: auto; <div id="ss" style="widt ...
- maven基础学习
项目结构 src -main -java -package -test -java ...
- 利用开源jPlayer播放.flv视频文件
最近工作中用到视频播放,在网上搜索对比了好几款开源播放插件后,觉得 jPlayer 是比较不错的,故作此记录! 接下来先快速的展示一下 利用jPlayer播放.flv视频的效果: <!DOCTY ...
- ios 实现版本更新检查
注:这里网络请求用的是第三方框架:SVHTTPRequest /* 第一步: 根据应用名称搜索应用,然后根据应用绑定的ID在结果中筛选出我们要找的应用,并取出应用的AppID */ - (void)g ...
- JSP和Server的相互转化
[设计想法] [前置条件] 1. eclipse的web环境已经搭建OK 2. eclipse已经存在web项目"firstweb" [操作步骤] 1. "firstwe ...
- Python之路-python(面向对象一)
一.面向对象介绍 二.为什么要用面向对象开发 三.封装.继承.多态.类.方法 面向过程和面向对象的区别 编程范式: 一般情况下,拿到一个项目不同的两个人有不同的编写方式(相同的是固定的语法.数据结构) ...
- C#.NET序列化XML、JSON、二进制微软自带DLL与newtonsoft(json.net)
序列化是将对象转换成另一种格式(XML.json.二进制byte[]) JSON序列化 .NET中有三种常用的JSON序列化的类,分别是: Newtonsoft.Json.JsonConvert类(推 ...
- k近邻算法的Java实现
k近邻算法是机器学习算法中最简单的算法之一,工作原理是:存在一个样本数据集合,即训练样本集,并且样本集中的每个数据都存在标签,即我们知道样本集中每一数据和所属分类的对应关系.输入没有标签的新数据之后, ...
- (转)MVC设计模式学习总结
原文 : chenchun的博客 http://www.cnblogs.com/jobscn/archive/2011/11/08/2240725.html -------------------- ...