5109: Boolean Satisability

Boolean satisfiability problem (SAT) is known to be a very hard problem in computer science. In this problem you are given a Boolean formula, and you need to find out if the variables of a given formula can be consistently replaced by the values true or false in such a way that the formula evaluates to true. 
SAT is known to be NP-complete problem. Moreover, it is NP-complete even in case of 3-CNF formula (3-SAT). However, for example, SAT problem for 2-CNF formulae (2-SAT) is in P.
#SAT is the extension of SAT problem. In this problem you need to check if it is possible, and count the number of ways to assign values to variables. This problem is known to be #P-complete even for 2-CNF formulae. We ask you to solve #1-DNF-SAT, which is #SAT problem for 1-DNF formulae.
You are given a Boolean formula in 1-DNF form. It means that it is a disjunction (logical or) of one or more clauses, each clause is exactly one literal, each literal is either variable or its negation (logical not). 
Formally:
Your task is to find the number of ways to replace all variables with values true and false (all occurrences of the same variable should be replaced with same value), such that the formula evaluates to true.

输入

The only line of the input file contains a logical formula in 1-DNF form (not longer than 1000 symbols).
Logical operations are represented by ‘|' (disjunction) and ‘~' (negation). The variables are ‘A'...Z' and ‘a'...‘z' (uppercase and lowercase letters are different variables). The formula contains neither spaces nor other characters not mentioned in the grammar.

输出

Output a single integer ---- the answer for #SAT problem for the given formula.

样例输入

B|~B

样例输出

2

题意:‘|’代表析取,‘~’代表非,输入一串类似样例的字符串(‘~’符号选择性输入),字母区分大小写,根据图上的计算关系,用 0 或 1 替换字母,使结果为真,输出有几种替换方式(同种字母要同时替换)。


AC代码:

#include<stdio.h>
#include<string.h>
int main()
{
    char s[1005];
    gets(s);
    int l=strlen(s);
    int i;
    int flag=1;
    int a[30][5],A[30][5];  //分别记录大小写字母的‘非’情况
    memset(a,0,sizeof(a));
    memset(A,0,sizeof(A));
    for(i=0; i<l; i++)
    {
        if(s[i]=='|')
        {
            flag=1;
            continue;
        }
        if(s[i]=='~')
        {
            flag=0;
            continue;

        }

//对大小写字母分别考虑

        if(s[i]>='a'&&s[i]<='z')
        {
            if(flag)
                a[s[i]-'a'][0]=1;  //如果字母不是‘非’的情况 标记1
            else
                a[s[i]-'a'][1]=1;
        }
        else
        {
            if(flag)
                A[s[i]-'A'][0]=1;
            else
                A[s[i]-'A'][1]=1;
        }


    }
    flag=0;
    long long int sum=0;
    for(i=0; i<26; i++)
    {
        if((A[i][0]==1&&A[i][1]==1)||a[i][0]==1&&a[i][1]==1)
        {
            if(a[i][0]==1&&a[i][1]==1)
                sum++;
            if(A[i][0]==1&&A[i][1]==1)
                sum++;
            flag=1;
        }
        else
        {
            if(a[i][0]==1||a[i][1]==1)
                sum++;
            if(A[i][0]==1||A[i][1]==1)
                sum++;
        }


    }
    if(sum==1&&flag==0)
    {
        printf("1\n");
        return 0;
    }
    long long int num=1;
    for(i=0; i<sum; i++)
        num*=2;
    if(flag)
        printf("%lld\n",num);
    else
        printf("%lld\n",num-1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值