ACM学习历程—HDU1041 Computer Transformation(递推 && 大数)

时间:2021-12-05 19:09:50

Description

A sequence consisting of one digit, the number 1 is initially written into a computer. At each successive time step, the computer simultaneously tranforms each digit 0 into the sequence 1 0 and each digit 1 into the sequence 0 1. So, after the first time step, the sequence 0 1 is obtained; after the second, the sequence 1 0 0 1, after the third, the sequence 0 1 1 0 1 0 0 1 and so on.

How many pairs of consequitive zeroes will appear in the sequence after n steps?

Input

Every input line contains one natural number n (0 < n ≤1000).

Output

For each input n print the number of consecutive zeroes pairs that will appear in the sequence after n steps.

Sample Input

2

3

Sample Output

1

1

题目大意就是有0-> 10, 1->01这两种变换,起始状态是1,让求某次变换后连续两个0的个数,此处有且仅两个0连续。

首先枚举前几项的话

0:1

1:01

2:1001

3:01101001

4:1001011001101001

5:01101001100101101001011001101001

……

发现两个个规律,

1:

所有项前一半和后一半互反,此外,偶数项对称。

想来也是,只要满足某个前一项前一半和后一半互反,0->10,1->01后,自然造成后一项同样互反的形式。

同样的前一个偶数项的对称会导致后面奇数项的前一半和后一半都对称,自然导致后一个偶数项对称。

此处严谨证明应由数学归纳法。

2:

后一项等于前一项取反拼上前一项。

发现奇数项由于前后互反,在交接处会形成01,那么下一项在对称情况下,交界处必形成1001。所以偶数项的0对会多生成一个。

有了这些就知道了两项间的关系。

于是由2得:

zero[i] = zero[i-1]+one[i-1]+(i-1)%2;

one[i] = zero[i-1]+one[i-1];

由于递推式看起来增长速度就和费波拉契有的一比,估计需要大数。实测确实需要。

代码:

import java.math.BigInteger;
import java.util.Scanner; public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
BigInteger one[] = new BigInteger[];
BigInteger zero[] = new BigInteger[];
one[] = new BigInteger("");
one[] = new BigInteger("");
zero[] = new BigInteger("");
zero[] = new BigInteger("");
for (int i = ; i <= ; ++i)
{
zero[i] = zero[i-].add(one[i-]).add(new BigInteger(Integer.toString((i-)%)));
one[i] = zero[i-].add(one[i-]);
}
int n;
while (input.hasNext())
{
n = input.nextInt();
System.out.println(zero[n]);
}
}
}