poj3295

本题中最多5个命题变项:p,q,r,s,t

每个有0,1两种取值,所以总共32种情况,分别枚举即可。

对于每种情况,计算表达式的值,如果有结果为0的则输出not

难点在于如何计算表达式的值,我们采用递归的方法,把表达式分为一或两个子表达式,并把参数end(本表达式的结束位置)传给上一层,一遍上一层获取第二个子表达式的起始位置。最后通过两个子表达式的结束位置,得到整个表达式的结束位置。

end是本表达式的最后一位的下标,即本表达式的长度减一。

所以 end = 2 + end1 + end2;

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;

string p;
bool v[5];

bool getValue(string p, int &end)
{
	bool a, b;
	int end1, end2;

	if (p[0] >= 'p')
	{
		end = 0;
		return v[p[0] - 'p'];
	}
	if (p[0] == 'N')
	{
		a = getValue(p.substr(1, p.length() - 1), end1);
		end = end1 + 1;
		return !a;
	}
	a = getValue(p.substr(1, p.length() - 1), end1);
	b = getValue(p.substr(end1 + 2, p.length() - 1), end2);
	end = 2 + end1 + end2;
	switch (p[0])
	{
	case 'K':
		return a && b;
	case 'A':
		return a || b;
	case 'C':
		return !a || b;
	case 'E':
		return !(a ^ b);
	}
	return 0;
}

int main()
{
	bool ok;

	freopen("D:\\t.txt", "r", stdin);
	while (getline(cin, p) && p != "0")
	{
		ok = true;
		for (int i = 0; i < 32; i++)
		{
			for (int j = 0; j < 5; j++)
				v[j] = (i >> j) % 2;
			int x;
			if (!getValue(p, x))
			{
				ok = false;
				break;
			}
		}
		if (ok)
			cout << "tautology" << endl;
		else
			cout << "not" << endl;
	}
	return 0;
}
posted @ 2011-02-01 14:23  金海峰  阅读(1794)  评论(1编辑  收藏  举报