构造法

poj3295

题目不难,就是题意有点难理解(英语不好啊...)

题目的意思是一个式子只有pqrst和KANCE组成(一开始理解成小写字母都是变量了,不知道该如何枚举了),然后判断式子是否是永真式

用栈来进行计算,遇到变量入栈,遇到操作符取出栈中元素,运算结果再入栈,最后栈中剩余的结果就是最终计算的结果。

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>

using namespace std;

stack<int> s;
int pp,qq,rr,ss,tt;

bool isvalue(char a)
{
     switch(a)
    {
        case ‘p‘:s.push(pp);return true;
        case ‘q‘:s.push(qq);return true;
        case ‘r‘:s.push(rr);return true;
        case ‘s‘:s.push(ss);return true;
        case ‘t‘:s.push(tt);return true;
    }
    return false;
}

void operators(char op)
{
    switch(op)
    {
        case ‘K‘:
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(x&&y);
                break;
            }
        case ‘A‘:
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(x||y);
                break;
            }
        case ‘C‘:
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push((!x)||y);
                break;
            }
        case ‘E‘:
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(x==y);
                break;
            }
        case ‘N‘:
            {
                int x=s.top();
                s.pop();
                s.push(!x);
                x=s.top();
                //printf("re:%d\n",x);
                break;
            }
    }
    return;
}

int main()
{
   char a[110];
   while(cin>>a&&a[0]!=‘0‘)
   {
       int len = strlen(a);
       bool flag=1;
       for(pp=0;pp<=1;pp++)
       {
           for(qq=0;qq<=1;qq++)
           {
               for(rr=0;rr<=1;rr++)
               {
                   for(ss=0;ss<=1;ss++)
                   {
                       for(tt=0;tt<=1;tt++)
                       {
                           for(int i=len-1;i>=0;i--)
                           {
                               if(!isvalue(a[i]))
                                  operators(a[i]);
                           }
                           flag=s.top();
                           s.pop();
                           if(!flag) break;
                       }
                       if(!flag) break;
                   }
                   if(!flag) break;
               }
               if(!flag) break;
           }
           if(!flag) break;
       }
       if(flag)  cout<<"tautology"<<endl;
       else cout<<"not"<<endl;
   }
}
时间: 2024-08-06 20:38:04

构造法的相关文章

利用子集构造法实现NFA到DFA的转换

概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够比较方便的机械实现且识别能力方面也和NFA相当.本次实验采用子集构造法来实现不带空弧的由NFA到DFA的转换. 子集构造法的算法如下: 设NFA为M=(K,Σ,f,S0,Z),则构造相应的DFA  M′=(Q,Σ,f′,I0,F)①取I0=S0:②对于状态集Q中任一尚未标记的状态qi={Si1,Si

生成子集 (增量构造法)

使用增量构造法可以构造出升序数组arr的不重复子集,并且按字典序排序 #include<bits/stdc++.h> using namespace std; int arr[16]; inline void print_subset(int *index, int cur, int n)///cur值这里可以理解为在这个堆栈层子集的集合数 { for(int i=0; i<cur; i++) {printf("%d ", arr[index[i]]);} if(cu

【算法竞赛入门经典】7.3子集生成【增量构造法】【位向量法】【二进制法】

7.3.1增量构造法 思路:一次选出一个元素放到集合中.自己对于递归的理解还是不够,这里虽然没有明确给出递归停止条件,但是如果无法继续添加元素,就不会再继续递归,然后就是我头疼的回溯啦. #include<stdio.h> int num[4],n; void A(int n,int *a,int ans) { for(int i = 0; i < ans; i ++)//打印当前元素 printf("%d ",a[i]); printf("\n"

子集生成——增量构造法+位向量法+二进制法

1.增量构造法: 原理图: 1 // 此算法仅用于输出下标,实际运用应输入另一个数组来进行数据的储存 2 #include <bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define INF 0X3f3f3f3f 7 const ll MAXN = 1e3 + 7; 8 const ll MOD = 1e9 + 7; 9 int a[10];

后缀数组 DC3构造法 —— 详解

学习了后缀数组,顺便把DC3算法也看了一下,传说中可以O(n)复杂度求出文本串的height,先比较一下倍增算法和DC3算法好辣. DC3 倍增法 时间复杂度 O(n)(但是常数很大)   O(nlogn)(常数较小) 空间复杂度   O(n)    O(n) 编程复杂度    较高   较低 由于在时间复杂度上DC3的常数比较大,再加上编程复杂度比较高,所以在解决问题的时候并不是最优选择.但是学到了后缀数组还是补充一下的好点. DC3算法的实现: 1:先把文本串的后缀串分成两部分,第一部分是后

Codeforces Round #276 (Div. 2)C. Bits(构造法)

这道题直接去构造答案即可. 对于l的二进制表示,从右到左一位一位的使其变为1,当不能再变了(再变l就大于r了)时,答案就是l. 这种方法既可以保证答案大于等于l且小于等于r,也可以保证二进制表示时的1最多. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include&l

uva1605 - Building for UN(构造法)

这道题构造出的结果很妙,考察思维能力.就两层,每层都n*n个格子,第一层第i行都放国家i,第二层第j列都放国家j. 需要注意的是ASCII中A至Z在a至z的前面(数字小),而且它们两组不挨着.所以需要char c(int i)这个函数. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map>

uva120 Stacks of Flapjacks (构造法)

这个题没什么算法,就是想出怎么把答案构造出来就行. 思路:越大的越放在底端,那么每次就找出还没搞定的最大的,把它移到当前还没定好的那些位置的最底端,定好的就不用管了. 这道题要处理好输入,每次输入的一行中是带空格的,以换行符结束一组数据的输入,那么用getline()函数.再用stringstream(这个可以自动转格式),非常方便的就处理了输入的问题.另外注意max_element和min_element都是左闭右开的. #include<iostream> #include<cstd

POJ 3295-Tautology(构造法+栈)

Tautology Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9936   Accepted: 3774 Description WFF 'N PROOF is a logic game played with dice. Each die has six faces representing some subset of the possible symbols K, A, N, C, E, p, q, r, s,

(白书训练计划)UVa 1605 Building for UN(构造法)

题目地址:UVa 1605 一道答案特判的题.最简单的方法是只构造两层,第一层中第i行全是i国家,第二层中第i列全是i国家.这样就保证了所有的国家都会相邻. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h&