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:
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:
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.
x | y | x|y |
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
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:
- Ai is an expression that denotes value of ith bit of number A.
- Bi is an expression that denotes value of ith bit of number B.
- (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.
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;
}