zoukankan      html  css  js  c++  java
  • bool树的计算

    1.题目大意: http://acm.hnu.cn/online/?action=problem&type=show&id=12022&courseid=186
    在布尔逻辑中,析取范式(DNF)是逻辑公式的标准化(或规范化),它是合取子句的析取。一个逻辑公式被认为是 DNF 的,当且仅当它是一个或多个文字的一个或多个合取的析取。同合取范式(CNF)一样,在 DNF 中的命题算子是与、或和非。非算子只能用做文字的一部分,这意味着它只能领先于命题变量。
    简单来说,析取范式是一些字句的逻辑或,而它的字句是一个合取范式;合取范式是一些字句的逻辑或,而它的字句是一个析取范式。
    本题中,逻辑树最深的节点是一个逻辑与,然后逻辑的与和或在每层交替出现。从最下层为一数起,奇数层是逻辑与,偶数层是逻辑或。

    假设A=False,  B=True,  C=False,  D=True,  E=False那么这颗bool树的最终结果为false

    上图输入数据形式为:((F(TF))(TF))

    题解:既然是一颗树,那么很自然的会想到要建一棵树,可是数据给的很恶心,要想建好一棵树然后再来求解貌似不太好实现(不信你可以试试,反正我的失败了)。

    后来灵光一闪,让我看出了端倪,树不是一层一层的吗,深搜不也是一层一层的吗,我每次遇到一个‘(’号,就进行一次深搜,遇到‘)’便结束搜索。遇到T或者F便先保存,最后根据该次搜索的深度来决定是用或操作还是用与操作。

    写好提交,果断AC,爽歪歪啊

    View Code
    #include<iostream>
    #include
    <string>
    using namespace std;

    char str[32005];
    int len;
    int visit[32005];

    int dfs(int s,int dep)
    {
    int i,j,ans,v[3],num[3],k,temp;
    k
    =0;
    memset(v,
    0,sizeof(v)); //由于bool只有0和1,结果只可能有两个,对结果判重
    for(i=s;i<len;i++)
    {
    if(!visit[i])
    {
    visit[i]
    =1;
    if(str[i]=='(') //深度加一
    {
    temp
    =dfs(i+1,dep+1); //在下一层中计算结果并返回
    if(!v[temp])
    {
    v[temp]
    =1;
    num[k
    ++]=temp;
    }
    }
    else if(str[i]=='T' || str[i]=='F') //本身深度,直接保存结果
    {
    if(str[i]=='T')
    temp
    =1;
    else if(str[i]=='F')
    temp
    =0;
    if(!v[temp])
    {
    v[temp]
    =1;
    num[k
    ++]=temp;
    }
    }
    else if(str[i]==')') //该深度计算结束
    {
    break;
    }
    }
    }
    ans
    =num[0];
    if(dep%2==0) //偶数层用与操作
    {
    for(j=1;j<k;j++)
    {
    ans
    =ans&num[j];
    }
    }
    else //奇数层用或操作
    {
    for(j=1;j<k;j++)
    {
    ans
    =ans|num[j];
    }
    }
    return ans;
    }

    int main()
    {
    int t=1,dd,i,ans,maxdd;
    freopen(
    "e:\\in.txt","r",stdin);
    while(scanf("%s",str)!=EOF)
    {
    if(strcmp(str,"()")==0)
    break;
    memset(visit,
    0,sizeof(visit));
    len
    =strlen(str);
    dd
    =0;maxdd=0; //计算最大深度
    for(i=0;i<len;i++)
    {
    if(str[i]=='(')
    {
    dd
    ++;
    if(dd>maxdd)
    maxdd
    =dd;
    }
    else if(str[i]==')')
    dd
    --;
    }
    if(maxdd%2==0) //由于题目要求最后一层深度要用与操作,而我的想法是深搜时偶数层相与奇数层相或,所以必须人工判别
    {
    ans
    =dfs(0,0);
    if(ans==0)
    {
    printf(
    "%d. false\n",t++);
    }
    else
    {
    printf(
    "%d. true\n",t++);
    }
    }
    else
    {
    ans
    =dfs(0,1);
    if(ans==0)
    {
    printf(
    "%d. false\n",t++);
    }
    else
    {
    printf(
    "%d. true\n",t++);
    }
    }
    }
    return 0;
    }
  • 相关阅读:
    【POJ 2923】Relocation(状压DP+DP)
    【HDU 2955】Robberies(DP)
    【POJ 2250】Compromise(最长公共子序列LCS)
    【URAL 1917】Titan Ruins: Deadly Accuracy(DP)
    【POJ 1273】Drainage Ditches(网络流)
    HDU2896 病毒侵袭[AC自动机]
    1516. 棋盘上的车[组合数学][状态压缩]
    [HAOI2012] 容易题[母函数]
    [HAOI2012] 高速公路
    [HAOI2012]Road
  • 原文地址:https://www.cnblogs.com/ka200812/p/2159780.html
Copyright © 2011-2022 走看看