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;
    }
  • 相关阅读:
    公用表表达式(CTE)的递归调用
    c# 如何让tooltip显示文字换行
    实战 SQL Server 2008 数据库误删除数据的恢复
    SQL SERVER数据库中 是否可以对视图进行修改删除
    asp.net中实现文件批量上传
    sql server 2008学习2 文件和文件组
    sql server 2008学习3 表组织和索引组织
    sql server 2008学习4 设计索引的建议
    sql server 2008学习10 存储过程
    .net 调用 sql server 自定义函数,并输出返回值
  • 原文地址:https://www.cnblogs.com/ka200812/p/2159780.html
Copyright © 2011-2022 走看看