https://www.bnuoj.com/v3/problem_show.php?pid=25653

【题意】

  • 给定一个3*3的九宫格,模拟一个停机坪。第一个格子一定是'*',代表take off area,其他的格子可能是'*','B','G'中的一种,'*'代表空地,'B','G'代表蓝色和绿色的飞机。
  • 每次操作都是一个飞机移动到take off area并起飞,在这个过程中其他飞机不能动。
  • 问有多少种飞机起飞的不同序列,同一种颜色的飞机是一模一样的。

【思路】

  • 这个停机坪最多有3^8=6561中不同的状态,可以考虑用三进制状压。
  • 状态之间可以转移。比如:

可以由转移来,也就是当前的出队序列就是B+pre的出队序列。

可以由转移来,也就是当前的出队序列就是G+pre的出队序列。

  • 这个出队序列也可以状压,为了表示方便,我们把当前的出队序列表示为pre的出队序列后面接上B或G,这样就可以用[pre]*3+1或[pre]*3+2表示当前状态。
  • 使用set可以自动去重,去掉重复的状态。

【Accepted】

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
const int maxn=;
const int inf=0x3f3f3f3f;
char s[][];
int a[];
int dig[];
set<int> dp[maxn];
set<int>:: iterator it;
bool v[][];
int dir[][]={{,},{,},{,-},{-,}};
void init()
{
dig[]=;
for(int i=;i<=;i++)
{
dig[i]=dig[i-]*;
}
} void BFS()
{
queue<pair<int,int> >Q;
memset(v,false,sizeof(v));
Q.push(make_pair(,));
v[][]=true;
while(!Q.empty())
{
int x=Q.front().first;
int y=Q.front().second;
Q.pop();
// cout<<x<<" "<<y<<endl;
for(int i=;i<;i++)
{
int xx=x+dir[i][];
int yy=y+dir[i][];
if(v[xx][yy])
{
continue;
}
if(xx<||x>=||y<||y>=)
{
continue;
}
v[xx][yy]=true;
if(s[xx][yy]=='*')
{
Q.push(make_pair(xx,yy));
}
}
}
} void DP()
{
dp[].insert();
for(int i=;i<dig[];i++)
{
int now=i;
for(int j=;j<;j++)
{
a[-j]=now%;
now/=;
}
for(int j=;j<;j++)
{
for(int k=;k<;k++)
{
if(a[j*+k]==)
{
s[j][k]='*';
}
else if(a[j*+k]==)
{
s[j][k]='B';
}
else
{
s[j][k]='G';
}
}
}
BFS();
for(int j=;j<;j++)
{
for(int k=;k<;k++)
{
if(v[j][k]&&s[j][k]=='B')
{
int pre=i-*dig[-*j-k];
for(it=dp[pre].begin();it!=dp[pre].end();it++)
{
dp[i].insert(*(it)*+);
}
}
else if(v[j][k]&&s[j][k]=='G')
{
int pre=i-*dig[-*j-k];
for(it=dp[pre].begin();it!=dp[pre].end();it++)
{
dp[i].insert(*(it)*+);
}
}
}
}
}
}
int main()
{
init();
DP();
int cas=;
while(~scanf("%s%s%s",s[],s[],s[]))
{
for(int i=;i<;i++)
{
for(int k=;k<;k++)
{
if(s[i][k]=='*')
{
a[*i+k]=;
}
else if(s[i][k]=='B')
{
a[*i+k]=;
}
else
{
a[*i+k]=;
}
}
}
int now=;
for(int i=;i<;i++)
{
now+=a[i]*dig[-i];
}
printf("Case %d: ",++cas);
cout<<dp[now].size()<<endl;
} return ;
}

    

【状压+状态转移】A Famous Airport Managere的更多相关文章

  1. 【noip2016提高组day2T3】【愤怒的小鸟】状压dp转移时的集合包含

    (上不了p站我要死了,图来自百度,侵权度娘背锅) 调死我了... 标题就说明了,死在了集合包含上.因为这道题与其他的状压题不同,其他的题基本上都是要求集合不重合,而这道题完全是可以的. 废话不多说,先 ...

  2. bzoj1054: [HAOI2008]移动玩具 状压+爆搜即可

    题意:在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初的玩具状态 ...

  3. BZOJ1076 [SCOI2008]奖励关 【状压dp + 数学期望】

    1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3074  Solved: 1599 [Submit][Sta ...

  4. CF580D Kefa and Dishes 状压dp

    When Kefa came to the restaurant and sat at a table, the waiter immediately brought him the menu. Th ...

  5. codevs1358棋盘游戏(状压dp)

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master     题目描述 Description 这个游戏在一个有10*10个格子的棋盘上进行,初 ...

  6. Codeforces.662C.Binary Table(状压 FWT)

    题目链接 \(Description\) 给定一个\(n\times m\)的\(01\)矩阵,你可以选择一些行和一些列并将其中所有的\(01\)反转.求操作后最少剩下多少个\(1\). \(n\le ...

  7. P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper 状压dp

    这个状压dp其实很明显,n < 18写在前面了当然是状压.状态其实也很好想,但是有点问题,就是如何判断空间是否够大. 再单开一个g数组,存剩余空间就行了. 题干: 题目描述 A little k ...

  8. 洛谷 P3112 后卫马克 —— 状压DP

    题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...

  9. ARC 093 F Dark Horse 容斥 状压dp 组合计数

    LINK:Dark Horse 首先考虑1所在位置. 假设1所在位置在1号点 对于此时剩下的其他点的方案来说. 把1移到另外一个点 对于刚才的所有方案来说 相对位置不变是另外的方案. 可以得到 1在任 ...

随机推荐

  1. 总结用CoreText绘制文本时遇到的问题以及解决办法

    关于CoreText不做解释.用的人自然知道这个是干什么的. 功能非常强大,可以绘制文本,图片等. 这次用的Xcode7.0的版本.所以之前很多方法,现在不能用.也不是不能用,就是有黄色警告很不爽. ...

  2. Snort里的规则目录文件解读(图文详解)

    不多说,直接上干货! snort的规则啊,是基于文本的,它通常存在于snort程序目录中或者子目录中,规则文件按照不同的组,进行分类存放的. snort的安装目录 [root@datatest sno ...

  3. Jquery插件jqprint-0.3.js实现打印

    1.首先引用Jquery和jqprint-0.3.js(依赖于Jquery的) <script language="javascript" src="jquery- ...

  4. 开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码

    开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows

  5. SQL将查询出来的多列的值拼接成一个字符串

    -- 单列拼接,先查出一行,再加上逗号,接着拼接 查出的下一行 SELECT GROUP_CONCAT(user_id) FROM user; -- result 160,160,160,196 -- ...

  6. NOT IN、NOT EXISTS的相关子查询改用LEFT JOIN--sql2000性能优化

    参考文章:SQL SERVER性能优化综述(很好的总结,不要错过哦) 数据库:系统数据库 子查询的用法 子查询是一个 SELECT 查询,它嵌套在 SELECT.INSERT.UPDATE.DELET ...

  7. PHP文件及目录考察点

    文件读取/写入操作 fopen()函数 用来打开一个文件,打开时需要指定打开模式 打开模式 模式 |作用 --- |--- 'r' |只读方式打开,将文件指针指向文件头. 'r+' |读写方式打开,将 ...

  8. WebStorm改变字体大小以及更换背景颜色

    参考文章:https://blog.csdn.net/weixin_42676530/article/details/82961279

  9. vue中的main.js打开直接报错问题解决

    安装好后也是报这样的错,是因为WebStorm默认使用的是ES5的语法,改成ES6就可以了.   解决方案:    

  10. UML-画类图与交互图的顺序

    并行.画完交互图,在画类图.交替进行.