• Codeforces913E. Logical Expression


    现有串x=11110000,y=11001100,z=10101010,通过这三个串只用与或非三种操作到达给定的串,优先级非>或>与,可以加括号,问表达式最短的里面字典序最小的是谁,有<=10000个询问。

    一个串,经过某种变换,到达另一个串,这种转移关系用图论极其合适。那么问题就转化成了一个最短路问题,其中最短包含题目的两个条件。

    然而,“某种变换”,即与或非,能否进行,跟优先级息息相关的。这里所关系到的优先级其实指的是最后一次操作的优先级。因此把最后一次操作是谁也列入状态。

    然后就划一下优先级,可以发现括号和非同级(3),然后与(2),然后或(1)。这样就可以转移了:>=3级的可以加非,>=2级的可以加与,>=1级的可以加或,而与和或都需要枚举其他所有不低于当前状态优先级的状态来转移,所以复杂度(n^2*log(n)*字符串比较),大约是(n^3)。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 //#include<assert.h>
     5 #include<algorithm>
     6 #include<string>
     7 #include<queue>
     8 #include<iostream>
     9 using namespace std;
    10 
    11 int n=256,x=240,y=204,z=170;
    12 
    13 bool ls(const string &a,const string &b)
    14 {
    15     if (a.length()!=b.length()) return a.length()<b.length();
    16     return a<b;
    17 }
    18 
    19 #define maxn 311
    20 string dis[maxn][3];
    21 struct qnode
    22 {
    23     int id,p;
    24     bool operator < (const qnode &b) const {return ls(dis[id][p],dis[b.id][b.p]);}
    25     bool operator > (const qnode &b) const {return ls(dis[b.id][b.p],dis[id][p]);}
    26 };
    27 priority_queue<qnode,vector<qnode>,greater<qnode> > q;
    28 void insert(int a,int b,string s)
    29 {
    30     if (dis[a][b].empty() || ls(s,dis[a][b]))
    31     {
    32         dis[a][b]=s;
    33         q.push((qnode){a,b});
    34     }
    35 }
    36 void dijkstra()
    37 {
    38     insert(x,2,"x");
    39     insert(y,2,"y");
    40     insert(z,2,"z");
    41     while (!q.empty())
    42     {
    43         const qnode now=q.top(); q.pop();
    44         if (now.p==2)
    45         {
    46             insert(now.id^(n-1),2,"!"+dis[now.id][now.p]);
    47             insert(now.id,1,dis[now.id][now.p]);
    48         }
    49         else if (now.p==1)
    50         {
    51             for (int i=0;i<n;i++) if (i!=now.id)
    52                 for (int j=1;j<=2;j++)
    53                     if (!dis[i][j].empty())
    54                     {
    55                         insert(now.id&i,1,dis[now.id][1]+"&"+dis[i][j]);
    56                         insert(now.id&i,1,dis[i][j]+"&"+dis[now.id][1]);
    57                     }
    58             insert(now.id,0,dis[now.id][now.p]);
    59             insert(now.id,2,"("+dis[now.id][now.p]+")");
    60         }
    61         else
    62         {
    63             for (int i=0;i<n;i++) if (i!=now.id)
    64                 for (int j=0;j<3;j++)
    65                     if (!dis[i][j].empty())
    66                     {
    67                         insert(now.id|i,0,dis[now.id][0]+"|"+dis[i][j]);
    68                         insert(now.id|i,0,dis[i][j]+"|"+dis[now.id][0]);
    69                     }
    70             insert(now.id,2,"("+dis[now.id][now.p]+")");
    71         }
    72     }
    73 }
    74 
    75 int T;
    76 int main()
    77 {
    78     dijkstra();
    79     scanf("%d",&T);
    80     while (T--)
    81     {
    82         int now=0;
    83         for (int j=0,x;j<8;j++) scanf("%1d",&x),(x && (now+=(1<<j)));
    84         cout<<dis[now][0]<<endl;
    85     }
    86     return 0;
    87 }
    View Code

    然而由于最长串是非常短的,所以也可以n^2*最长串*字符串比较,即更新到没有状态被更新时退出最短路。

  • 相关阅读:
    学习视频资料下载论坛
    2007年12月英语四级预测作文大全1
    主板报警声音大全
    2007年12月英语四级预测作文大全1
    主板报警声音大全
    LOGO在线制作
    武汉之行收获
    武汉之行
    心灵小栈: 镌刻在地下500米的母爱
    一道终身受益的测试题
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8251312.html
Copyright © 2020-2023  润新知