POJ 1286 Necklace of Beads(Polya计数原理)

题目链接

看着真痛苦啊,看组合数学上的东西看不懂。。。看了好多人的题解。。根本不懂为毛线是这样做。。。公式是肿么推导的。。。

PS:和外校的某牛交流了后,给我发了个PDF的程序设计中的组合数学,话说那本书是以前还看过,确实这本书上的例题更简单一点。。。

 

貌似这样的,这个公式G是代表可以置换的方式个数,如此题,可以转0个 1个 ...n-1,共n种可能,翻转也有n种置换方式,奇偶数的时候情况不同,而后便就是代表每一种置换都不改变的可能,如这个题,有4个点的时候,转0度的时候肯定都不改变,3^4,而转1个也就是90度的时候,有3种(颜色全部相同的时候),转2个的时候有3^2次方,也就是不相邻的两个点要颜色相同,转3个时候 也是 3个。。。就是题解中gcd来确定的。。。然后翻转的时候,如果是偶数,如4,因为可以两个点为轴也可以以空挡为轴,以点为轴的时候就是2*3*3*3(有两个点必须相同另两个点任意),以空挡为轴的时候就是2*3*3(必须两个相同一对的),奇数的时候必须以点到一个空挡为轴,如5的时候,就是5*3*3*3(两个相同一对+轴上的点)。公式应该就这么个意思。。。

                                                                                                                                                                          2012.07.24    19:47

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <math.h>

 4 #define eps 0.0000001

 5 int gcd(int a,int b)

 6 {

 7     return b == 0?a:gcd(b,a%b);

 8 }

 9 int main()

10 {

11     double sum = 0;

12     int i,n;

13     __int64 s;

14     while(scanf("%d",&n)!=EOF)

15     {

16         sum = 0;

17         if(n < 0) break;

18         if(n == 0)

19         {

20             printf("0\n");

21             continue;

22         }

23         for(i = 1; i <= n; i ++)//旋转的时候

24         {

25             sum += pow(3,gcd(i,n));

26         }

27         if(n%2==0)//翻转的时候

28         {

29             sum += pow(3,n/2+1)*n/2;

30             sum += pow(3,n/2)*n/2;

31         }

32         else

33         {

34             sum += pow(3,n/2+1)*n;

35         }

36         s = (__int64)(sum/2/n+eps);

37         printf("%I64d\n",s);

38     }

39     return 0;

40 }

你可能感兴趣的:(poj)