poj 1747 -- Expression(递归)

 

 

 

 http://poj.org/problem?id=1747

 

 

Expression
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 476 Accepted: 297

Description

It is known that Sheffer stroke function (NOT-AND) can be used to construct any Boolean function. The truth table for this function is given below:
Truth table for Sheffer stroke function
xyx|y
001
011
101
110

Consider the problem of adding two binary numbers A and B, each containing N bits. The individual bits of A and B are numbered from 0 (the least significant) to N-1 (the most significant). The sum of A and B can always be represented by N+1 bits. Let's call most significant bit of the sum (bit number N) the overflow bit.

Your task is to construct a logical expression using the Sheffer stroke function that computes the value of the overflow bit for arbitrary values of A and B. Your expression shall be constructed according to the following rules:
  1. Ai is an expression that denotes value of ith bit of number A.
  2. Bi is an expression that denotes value of ith bit of number B.
  3. (x|y) is an expression that denotes the result of Sheffer stroke function for x and y, where x and y are expressions.

When writing the index, i, for bits in A and B, the index shall be written as a decimal number without leading zeros. For example, bit number 12 of A must be written as A12. The expression should be completely parenthesized (according to the 3rd rule). No blanks are allowed inside the expression.

Input

The input contains a single integer N (1 <= N <= 100).

Output

Write to the output an expression for calculating overflow bit of the addition of two N-bit numbers A and B according to the rules given in the problem statement.
Note: The stroke symbol ( | ) is an ASCII character with code 124 (decimal).

The output size shall not exceed 50*N bytes.

Sample Input

2

Sample Output

((A1|B1)|(((A0|B0)|(A0|B0))|((A1|A1)|(B1|B1))))

Source

 

具体的推导过程是DISCUSS的。

其实看Sample Output 也是可以发现的

只是不是那么简单。。。

 

 

/*
高手们结果是:
//记*为n=k-1时的表达式,则n=k时,表达式为
//((An-1|Bn-1)|(*|((An-1|An-1)|(Bn-1|Bn-1))))
//则递归函数的结构为:先输出*左边的部分,然后输出*,再输出*右边的部分。
//边界条件为n=1,此时表达式为((A0|B0)|(A0|B0))。
//虽然不知道怎么得来的,但测试数据是可以分析的。
//题目要求的是给你的这个 n 位二进制数,判断是否任意的两个数的和是否进位了。
//这样分析:判断是否进位,先看最高位是哪两个数,如果最高位都是 1 ,必然进位。
//就有 1|1 = 0,0|x = 1。所以就有(An-1|Bn-1)|*。
//这个 * 是求低位是否进位。同样有这样的递归,但最后一位,也就是A0+B0是否进位就要特别考虑了。
//因为它们没有低位的考虑。于是就有A0+B0的进位用(A0|B0)|(A0|B0)来判断。
//那是不是就是(An-1|Bn-1)|((An-2|Bn-2)...|((A0|B0)|(A0|B0)))呢?不是,刚才只能确定,当 An-1 和 Bn-1 都为
//1 时才具备这样的表达式。但如果 An-1,Bn-1 不全为 1 。就要另作考虑了。这样,考虑时就不必考虑都是 1 的
//情况。也就是说看这个表达式(An-1|Bn-1)|(*|?)。这里的 * 指低位是否进位。? 指对An-1和Bn-1不全为0时的进一步判断。
//可以看到,如果低位进位,则 *=1 否则 *=0。现在判断是否进位,只要An-1和Bn-1二者之一是否为 1 即可。
//注意到,An-1和Bn-1不全为 0 时,有 An-1|Bn-1=1 。也就是说,如果后面的表达式为 0 时才进位,否则不进位。
//那么,现在已经知道低位进位 *=1,否则*=0 。要做的是,使An-1和Bn-1两者之一是 1 时与 * 运算,有
//1|?=0,0|?=1。并且当两者都不是 1 时,有1|?=1,0|?=1。由于0|x=1,所以只需考虑 1|? 的情况。
//于是有当两者之一是 1 时,?=0,并且两者均为 0 时,?=1。于是有?=(An-1|An-1)|(Bn-1|Bn-1)
//这样,整个式子就是:((An-1|Bn-1)|(*|((An-1|An-1)|(Bn-1|Bn-1))))。
*/

//公式出来了递推式就很容易得出了

#include<iostream>
using namespace std;

void solve(int n)
{
	if(n==1)
		printf("((A0|B0)|(A0|B0))");
	else
	{
		printf("((A%d|B%d)|(",n-1,n-1);
		solve(n-1);
		printf("|((A%d|A%d)|(B%d|B%d))))",n-1,n-1,n-1,n-1);
	}
}

int main()
{
	int n;
	scanf("%d",&n);
	solve(n);
	printf("\n");
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值