1711 - puncher

发布时间:2010-04-29 23:03:50

解题报告:Puncher

题目来源:Northeastern Europe 1997

解法或类型:组合数学

作者:杨清玄

Puncher

Time Limit:10S  Memory Limit:10000K
Total Submit:18 Accepted:4

Description

Puncher is a device with several needles for making holes in tickets. At the factory there is a rectangular form with M rows and N columns, as shown in the picture (M=3, N=4), to make different punchers with 1, 2, ... , M*N needles. The rows and columns of needles are perpendicular to each other. The distance between rows is equal to the distance between columns. Obviously, it is possible to make 2M*N-1 different punchers in this way.

However, sometimes it is not possible to distinguish tickets that are perforated by different punchers. Let us assume that while punching two opposite borders of the ticket are parallel to the rows of the needles, the other pair of opposite borders being parallel to the columns of the needles. The number of the holes in a perforated ticket is always equal to the number of the needles in the corresponding puncher. A composition of the following transformations is allowed:

a ticket may be perforated on any side (axial symmetry),

it may be inserted into the puncher with any of its four borders downwards (rotation by 90, 180 and 270 degrees),

parallel translations are also available.


Your task is to write a program to determine how many actually different punchers can be made with an M*N form. Two punchers are considered actually different, if it is impossible to match using any combination of the above described operations the holes in the two tickets perforated by these punchers.

Input

The input file consists of two positive integer numbers M (not greater than 4) and N (not greater than 8) separated by a single space.

Output

The output file consists of a single integer indicating the number of the actually different punchers.

Sample Input

3 3

Sample Output

85

Source

Northeastern Europe 1997

解题思路:

本题是一道组合数学题目。这道题可以用群论来做。(但是需要一点小技巧)首先,本题的置换数量太多,有平移,旋转,对称这3种基本置换,以及这些置换彼此组合而成的无数种置换,生算一定是做不出来的。

我的方法是把最难搞的平移置换去掉,也就是说,所有我认为“合法”置方案都是不可平移的,也就是说,考虑M*N的一个布置方案,所谓的“合法”的方案就是这个方案的边界上一定有孔存在的方案。(并且M<=N

这样题目要求的M*N布置方案的数目就是所有小于或等于M*N的“合法”的布置方案的数目的和,那么题目变成了求一个M*N的“合法”的布置方案数,那么利用置换群我们可以知道

对于只有1行的方案只有两种置换,(不变,左右翻转)

剩下的情况中

对于一个M*NM=N)的一个“合法”的布置方案,总共只有4种置换,(不变,上下翻转,左右翻转,旋转180度);

对于一个M*M的“合法”的布置方案,总共有8种置换(多出来了,左转90度,右转90度,还有两条对角线翻转(这个是转90度和上下翻转的合成))

所以我们只要求出在这些置换下的不变的方案数就可以了(然后就用BURNSIDE

要解决这些问题,我的方法是计算了(M*N)的相邻两条边都存在孔的方案数,以及3条边都存在孔的方案数。

1,不变:

不变的数目很好求,因为只要满足“合法”的方案都是不变置换下的不变方案,这个可以轻易的用上面的两个方案数求出来。

2,上下翻转:

上下翻转的数目也很好求,因为只要考虑中位线上一半的布置数就可以了,这个也可以轻易的用上面的两个方案数求出来。

类似的,这8个变换的方案树都可以求出来,可以推出公式

数据结构:

用两个数组来存储相邻两边都存在孔的方案数,以及3条边都存在孔的方案数

时空分析:

时间复杂度为ON^2

空间复杂度为ON^2

源程序:

puncher.cpp

1711 - puncher

相关推荐