刷清橙OJ--A1049.命题逻辑

来源:互联网 发布:网络摄像头怎样安装 编辑:程序博客网 时间:2024/06/15 20:49
问题:
A1049. 命题逻辑
时间限制:1.0s   内存限制:512.0MB  
总提交次数:1175   AC次数:264   平均分:56.16
问题描述
  在命题逻辑中,每个变元可以取值为真或假,通过逻辑运算符连接得到逻辑表达式,逻辑表达式的值由逻辑变元的值计算得出。
  以下是常用的逻辑运算符。
  ~:表示否定,~P为真当且仅当P为假。
  >:蕴含,P>Q为真当且仅当Q为真或者P为假。
  ^:合取,P^Q为真当且仅当P和Q同为真。
  v:析取,PvQ为真当且仅当P和Q中至少一个为真。

  重言式是指无论变元如何取值其结果都为真的表达式,矛盾式是指无论变元如何取值其结果都为假的表达式。

  在表式逻辑表达式的时候,可以使用辅助符号来方便描述,一个辅助符号可能是另外两个变元或辅助符号运算的结果。
  为了使用辅助符号来表示否定运算,我们设置一个虚拟的辅助符号X0,使用X0和另一个变元运算P运算后即得到~P的结果。

  给定一系列辅助符号的定义,问最后一个辅助符号是重言式、矛盾式还是其他表达式。
输入格式
  输入数据第一行是两个整数n、m(1<=n<=4,1<=m<=10)。表示在输入中出现的变元不超过n个、辅助符号为m个,变元依次为P0, P1, ..., Pn-1,辅助符号依次为A0, A1, ..., Am-1。
  从第二行开始,依次描述A0,A1,…Am-1,并严格依照以下格式:
  Ai L ? R
  其中Ai依次为A0, A1, ..., Am-1。?可以为“~”、“>”、“^”、“v”。L和R可以是变元或者之前出现过的辅助符号。
  若?为“~”,则L必定为X0。
输出格式
  若Am-1为重言式,输出1。
  若Am-1为矛盾式,输出-1。
  若两者都不是,输出0。
样例输入
1 2
A0 X0 ~ P0
A1 A0 v P0
样例输出
代码:
 #include <iostream>#include <algorithm>#include <cstring>#include <math.h>#include <set>#include <vector>#include <sstream>using namespace std;/* * 1 2A0 X0 ~ P0A1 A0 v P0 ~:表示否定,~P为真当且仅当P为假。  >:蕴含,P>Q为真当且仅当Q为真或者P为假。  ^:合取,P^Q为真当且仅当P和Q同为真。  v:析取,PvQ为真当且仅当P和Q中至少一个为真。 */int n, m;bool anst = true;bool ansf = true;bool p[10];bool a[10];string x[10], y[10];char op[10];bool getvalue(string t) {   int tp;   if (t[0] == 'P') {      tp = t[1] - '0';      return p[tp];   } else if (t[0] == 'A') {      tp = t[1] - '0';      return a[tp];   }   return false;}void cal(int i){   if (x[i][0] == 'X' && op[i] == '~'){      a[i] = !getvalue(y[i]);      return;   }else{      bool tx = getvalue(x[i]);      bool ty = getvalue(y[i]);      switch (op[i]){         case '>':            a[i] = (!tx) | ty;            return;         case '^':            a[i] = tx & ty;            return;         case 'v':            a[i] = tx | ty;         default:            return;      }   }}void f(int i){   if (i == n){      for (int j = 0; j < m; j++){         cal(j);      }      if (a[m - 1]) ansf = false;      else anst = false;      return;   }   p[i] = true;   f(i + 1);   p[i] = false;   f(i + 1);}int main(){   cin>>n>>m;   string ts;   for (int i = 0; i < m; i++){      cin>>ts>>x[i]>>op[i]>>y[i];   }      f(0);   if (anst) cout<<1<<endl;   else if(ansf) cout<<-1<<endl;   else cout<<0<<endl;}

个人想法:代码是来自试题讨论的。非原创。得思路清晰才好。
原创粉丝点击