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 }