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 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只 ...
随机推荐
- javac编译、运行
java源码(包结构) 源码存放位置:C:/Users/liaolongjun/DeskTop/java/ package test; import test.sub.F; public class ...
- Indexing and Hashing
DATABASE SYSTEM CONCEPTS, SIXTH EDITION11.1 Basic ConceptsAn index for a file in a database system wo ...
- sql 在not in 子查询有null值情况下经常出现的陷阱
如果下:TempSalesPriceFixedValues表和SalesPriceFixedValues表,要求查询出在TempSalesPriceFixedValues表中且不在SalesPrice ...
- LeetCode Best Time to Buy and Sell Stock with Cooldown
原题链接在这里:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 题目: Say you hav ...
- meanshift
http://blog.jasonding.top/2014/10/14/Machine%20Learning/%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%8 ...
- perl基础
perl比较好的博客:http://www.cnblogs.com/cosiray/archive/2012/03/18/2404371.html 以分析一个简单的pm文件为例 # # オプションの取 ...
- yum下载rpm
yum下载rpm yum update --downloadonly --downloaddir=/root/rpm_package/ python-pip
- MyBatis(2):config.xml文件
前言 前一篇文章,讲了MyBatis入门,讲到了MyBatis有两个基本的配置文件,一个用来配置环境信息,一个用来写SQL语句.前者我把它命名为config.xml,config.xml的内容是: 1 ...
- echarts入门基础,画柱型图
注意:一定要自己引入echarts库 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- JSONP使用笔记
JSONP JSONP是实现跨域GET请求的一种方法, 原理上利用script标签可以动态加载JS文件, 将不同源站点的JSON数据加载到本网站来,如果给定回调函数,将回调函数名传递到服务器端, 在服 ...