zoukankan      html  css  js  c++  java
  • 【CodeForces】913 E. Logical Expression

    【题目】E. Logical Expression

    【题意】令x=11110000(2),y=11001100(2),z=10101010(2),n次询问,每次要求用[与][或][非][括号]构成含至多各1个xyz的表达式使得结果等于给定的数字(0~255),要求表达式最短(一样短时字典序最小)。n<=10000

    【算法】数学+最短路?

    【题解】实际上给的数字只有256种情况,所以思路是先预处理再直接回答询问。

    对每个表达式我们只关心其结果和最后进行的运算符优先级,所以至多有3*256种状态,令n=3*256。

    关于优先级,定义三层优先级,最高F为!和(),次高T为&,最低E为|,表达式的优先级为其最后计算的符号的优先级,低优先级遇到高优先级需要打括号

    令F[i]表示最高优先级结果为i的最短表达式,T[i]和E[i]同理,这三种优先级转移如下:

    一、F

    1.F[i]=min{ F[i] , "(" + E[i] + ")" }

    2.F[i]=min{ F[i] , "!" + F[i^255] }

    二、T

    1.T[i]=min{ T[i] , F[i] }

    2.T[i&j]=min{ T[i&j] , T[i]&T[j] }

    三、E

    1.E[i]=min{ E[i] , T[i] }

    2.E[i&j]=min{ E[i&j] , E[i]&E[j] }

    只需要这六种转移,三层优先级就可以实现循环转移,可以运用dijkstra,n个结点,转移连边,复杂度O(n^3)。或直接迭代实现至无法更新结束,复杂度O(n^2)。(复杂度分析不太清楚)

    最终答案就是ans=E[x],x为输入。

    #include<cstdio>
    #include<string>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    string f[300],t[300],e[300];
    char s[20];
    int n;
    bool cmp(string& a,string& b){return a.size()!=b.size()?a.size()<b.size():a<b;}
    bool modify(string& a,string b){return (a==""||cmp(b,a))?a=b,1:0;}
    int main(){
        f[240]="x";f[204]="y";f[170]="z";
        while(1){
            bool ok=0;
            for(int i=0;i<256;i++)if(e[i]!="")ok|=modify(f[i],"("+e[i]+")");
            for(int i=0;i<256;i++)if(f[i]!="")ok|=modify(f[i^255],"!"+f[i]);
            for(int i=0;i<256;i++)if(f[i]!="")ok|=modify(t[i],f[i]);
            for(int i=0;i<256;i++)if(t[i]!="")for(int j=0;j<256;j++)if(t[j]!="")ok|=modify(t[i&j],t[i]+"&"+t[j]);
            for(int i=0;i<256;i++)if(t[i]!="")ok|=modify(e[i],t[i]);
            for(int i=0;i<256;i++)if(e[i]!="")for(int j=0;j<256;j++)if(e[j]!="")ok|=modify(e[i|j],e[i]+"|"+e[j]);
            if(!ok)break;
        }
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s);int c=0;
            for(int j=0;j<8;j++)c|=((s[j]-'0')<<j);
            cout<<e[c]<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ReactNative学习-webView
    React Native学习-将 'screen', 'window' or a view生成图片
    React Native学习-measure测量view的宽高值
    React Native教程
    React Native学习-CameraRoll
    React Native学习-控制横竖屏第三方组件:react-native-orientation
    React Native学习-调取摄像头第三方组件:react-native-image-picker
    ReactNative学习-滑动查看图片第三方组件react-native-swiper
    MFC的简单加法器(二)
    MFC之目录结构及消息流转(一)
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8256525.html
Copyright © 2011-2022 走看看