zoukankan      html  css  js  c++  java
  • 【状压+状态转移】A Famous Airport Managere

    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】

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<set>
      8 #include<queue>
      9 using namespace std;
     10 const int maxn=6561;
     11 const int inf=0x3f3f3f3f;
     12 char s[3][4];
     13 int a[10];
     14 int dig[10];
     15 set<int> dp[maxn];
     16 set<int>:: iterator it;
     17 bool v[4][4];
     18 int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
     19 void init()
     20 {
     21     dig[0]=1;
     22     for(int i=1;i<=9;i++)
     23     {
     24         dig[i]=dig[i-1]*3;
     25     }
     26 }
     27 
     28 void BFS()
     29 {
     30     queue<pair<int,int> >Q;
     31     memset(v,false,sizeof(v));
     32     Q.push(make_pair(0,0));
     33     v[0][0]=true;
     34     while(!Q.empty())
     35     {
     36         int x=Q.front().first;
     37         int y=Q.front().second;
     38         Q.pop();
     39     //    cout<<x<<" "<<y<<endl; 
     40         for(int i=0;i<4;i++)
     41         {
     42             int xx=x+dir[i][0];
     43             int yy=y+dir[i][1];
     44             if(v[xx][yy])
     45             {
     46                 continue;
     47             }
     48             if(xx<0||x>=3||y<0||y>=3)
     49             {
     50                 continue;
     51             }
     52             v[xx][yy]=true;
     53             if(s[xx][yy]=='*')
     54             {
     55                 Q.push(make_pair(xx,yy));
     56             }
     57         }
     58     }
     59 }
     60 
     61 void DP()
     62 {
     63     dp[0].insert(0);
     64     for(int i=1;i<dig[8];i++)
     65     {
     66         int now=i;
     67         for(int j=0;j<9;j++)
     68         {
     69             a[8-j]=now%3;
     70             now/=3;
     71         }
     72         for(int j=0;j<3;j++)
     73         {
     74             for(int k=0;k<3;k++)
     75             {
     76                 if(a[j*3+k]==0)
     77                 {
     78                     s[j][k]='*';
     79                 }
     80                 else if(a[j*3+k]==1)
     81                 {
     82                     s[j][k]='B';
     83                 }
     84                 else
     85                 {
     86                     s[j][k]='G';
     87                 }
     88             }
     89         }
     90         BFS();
     91         for(int j=0;j<3;j++)
     92         {
     93             for(int k=0;k<3;k++)
     94             {
     95                 if(v[j][k]&&s[j][k]=='B')
     96                 {
     97                     int pre=i-1*dig[8-3*j-k];
     98                     for(it=dp[pre].begin();it!=dp[pre].end();it++)
     99                     {
    100                         dp[i].insert(*(it)*3+1);
    101                     }
    102                 }
    103                 else if(v[j][k]&&s[j][k]=='G')
    104                 {
    105                     int pre=i-2*dig[8-3*j-k];
    106                     for(it=dp[pre].begin();it!=dp[pre].end();it++)
    107                     {
    108                         dp[i].insert(*(it)*3+2);
    109                     }
    110                 }
    111             }
    112         }
    113     }
    114 }
    115 int main()
    116 {
    117     init();
    118     DP();
    119     int cas=0;
    120     while(~scanf("%s%s%s",s[0],s[1],s[2]))
    121     {
    122         for(int i=0;i<3;i++)
    123         {
    124             for(int k=0;k<3;k++)
    125             {
    126                 if(s[i][k]=='*')
    127                 {
    128                     a[3*i+k]=0;
    129                 }
    130                 else if(s[i][k]=='B')
    131                 {
    132                     a[3*i+k]=1;
    133                 }
    134                 else 
    135                 {
    136                     a[3*i+k]=2;
    137                 }
    138             }
    139         }
    140         int now=0;
    141         for(int i=0;i<9;i++)
    142         {
    143             now+=a[i]*dig[8-i];
    144         }
    145         printf("Case %d: ",++cas);
    146         cout<<dp[now].size()<<endl; 
    147     }
    148     
    149     return 0;    
    150 }
    View Code

        

  • 相关阅读:
    8. Andr&#233;nalin ★ Serial
    1 Acid burn ★ Nag,Name/Serial,Serial
    【CPP】字符串和格式化输入输出
    什么是生成器
    【python密码学编程】8.使用换位加密法加密
    【python密码学编程】6.凯撒加密法
    【CPP】数据和C
    【python密码学编程】7.暴力破解凯撒加密法
    HDOJ 4515 小Q系列故事——世界上最遥远的距离
    POJ1131 Octal Fractions
  • 原文地址:https://www.cnblogs.com/itcsl/p/7183829.html
Copyright © 2011-2022 走看看