poj 3295 Tautology 构造法

1.第二次做了还是没有思路

2.我是从字符串的长度考虑,如果长度=1 ,就会怎样 长度=3 就有多少种可能,并且打算用递归的算法,把一个字符串分解成几小部分来解,但是问题来了,我应该怎么分解对于一个字符串,第一个肯定是运算符,但是后面应该怎么拆分,拆分后又怎么能够利用子式。这些都无法解决

3. 看别人的解题思路,既然这和运算符有关的,那就考虑操作,这不就是我们学栈这个数据结构时的例题吗

3.同时我没有考虑枚举,我只考虑了肯定状态 即PP PNP,这些相同的的肯定能出现结果,不同的肯定不能出结果(对于一个小的式子来说)

转自https://www.cnblogs.com/kuangbin/archive/2012/08/13/2636855.html

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int MAXN=120;
int sta[MAXN];//数组实现堆栈
char str[MAXN];
int p,q,r,s,t;
void  DoIt()
{
    int top=0;
    int len=strlen(str);
    for(int i=len-1;i>=0;i--)
    {
        if(str[i]=='p') sta[top++]=p;
        else if(str[i]=='q') sta[top++]=q;
        else if(str[i]=='r') sta[top++]=r;
        else if(str[i]=='s') sta[top++]=s;
        else if(str[i]=='t') sta[top++]=t;
        else if(str[i]=='K')
        {
            int t1=sta[--top];
            int t2=sta[--top];
            sta[top++]=(t1&&t2);
        }
        else if(str[i]=='A')
        {
            int t1=sta[--top];
            int t2=sta[--top];
            sta[top++]=(t1||t2);
        }
        else if(str[i]=='N')
        {
            int t1=sta[--top];
            sta[top++]=(!t1);
        }
        else if(str[i]=='C')
        {
            int t1=sta[--top];
            int t2=sta[--top];
            if(t1==1&&t2==0)sta[top++]=0;
            else sta[top++]=1;
        }
        else if(str[i]=='E')
        {
            int t1=sta[--top];
            int t2=sta[--top];
            if((t1==1&&t2==1)||(t1==0&&t2==0)) sta[top++]=1;
            else sta[top++]=0;
        }
    }
}
bool solve()
{
    for(p=0;p<2;p++)
      for(q=0;q<2;q++)
        for(r=0;r<2;r++)
           for(s=0;s<2;s++)
              for(t=0;t<2;t++)
              {
                  DoIt();
                  if(sta[0]==0)return false;
              }
    return true;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%s",&str))
    {
        if(strcmp(str,"0")==0)break;
        if(solve())printf("tautology\n");
        else printf("not\n");
    }
    return 0;
}



同样用栈poj1068 Parencodings

也是模拟运算符类似的

其中最妙的是相减可以得到两个右括号之间的左括号数目

#include <iostream>
#include <cstring>
#include<stdio.h>
#include <stack>
using namespace std;

int main()
{
    int t,kk[100];
    cin>>t;
    while(t--)
    {
        stack<int> b;
        int len,a,t=0,k;
        cin>>len;

        for(int i=1; i<=len; i++)
        {
            cin>>a;
            kk[i]=a-t;
            t=a;
            for(int j=0; j<kk[i]; j++)
            {
                b.push(0);
            }

            if(b.top()==0)
            {
                b.pop();
                b.push(1);
                cout<<1;
                if(i==len) cout<<endl;
                else cout<<" ";
            }
            else
            {
                int ans=0;
                while(b.top()!=0)
                {
                    ans+=b.top();
                    b.pop();
                }
                b.pop();
                b.push(ans+1);
                cout<<ans+1;
                if(i==len) cout<<endl;
                else cout<<" ";
            }
        }




    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lirui7610/article/details/79976120