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 }
posted @ 2012-07-24 16:22  Naix_x  阅读(222)  评论(0编辑  收藏  举报