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 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只 ...
随机推荐
- Ubuntu 常用工具、指令安装
修改source list,使用阿里云的软件源 sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sed - ...
- sql server中sql语句中单引号怎么转义?【转】
sql server有两个转义符: ' 默认情况下, '是字符串的边界符, 如果在字符串中包含', 则必须使用两个', 第1个'就是转义符 另一个转义符是" 当SET QUOTED_IDEN ...
- CocoaPods 学习
参考文章 git address 1.简绍:CocoaPods是一个负责管理iOS项目中第三方开源代码的工具. 2.安装过程: $ sudo gem install cocoapods $ pod s ...
- 启动Hive报错
Exception in thread "main" java.lang.RuntimeException: Hive metastore database is not init ...
- angularJs之$watch监听属性变化访问后台
- ReentrantReadWriteLock读写锁详解
一.读写锁简介 现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁.在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源:但是如果一个线 ...
- 获取Python安装目录
>>> import sys>>> path=sys.executable>>> print (path)C:\Users\jumz-G\AppD ...
- C# httprequest post 内容有百分号,部分特殊字符乱码问题
哎没办法,还没完全脱离.net,已经一半了. http://stackoverflow.com/questions/7908581/how-to-encode-http-post-parameters ...
- 互联网中级Javascript面试题
互联网中级Javascript面试题 1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制 ...
- JavaScript encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent()
URI: Uniform Resource Identifier encodeURI() And decodeURI() The encodeURI() function is used to en ...