sgu 208 Toral Tickets polya定理

题意:给你N和M,对于一个N*M的单面方格纸你可以对它的每个个格子黑白染色,然后把方格纸的长边卷起来,卷成一个圆柱体,然后再把两个短边形成的圆也接起来,形成一个游泳圈的形状(我们染的色只在游泳圈的外表面)。如果对于两种黑白染色方案,通过卷成这样的游泳圈后,是一样的,则这两种方案也是一样的。给定N,M<=20 ,求染色方案总数.

思路:polya定理

.当n!=m时,每一列上下可以滚动,每一行左右可以滚动,整个游泳圈可以上下倒置(也就是把游泳圈翻过来,明显此时左右也倒置了),所以总共有N*M*2种置换;

当n=m时,游泳圈不存在长边与短边,所以你可能第一次是把行卷成圆柱,也可能是先把列卷成圆柱,也就是可能把方格纸顺(或逆,只考虑其中一种即可)时针旋转90度的置换。所以置换总数应该是N*M*2*2.

需要高精 我用java写的

P.S. 在sgu交的时候需要把class名sgu208改为Solution

详见:http://hi.baidu.com/%CE%D2%CD%F9%C7%BD%C9%CF%D7%B2/blog/item/12e8faf4322423285c600826.html

 

  1 import java.math.*;
2 import java.util.*;
3 import java.io.*;
4 public class sgu208
5 {
6 static int n,m;
7 static int a[]=new int[500];
8 static boolean use[]=new boolean[500];
9 static BigInteger p[]=new BigInteger[500];
10 public static void make_biginteger()
11 {
12 p[0]=new BigInteger("1");
13 BigInteger multi=new BigInteger("2");
14 for(int i=1;i<=400;i++)
15 {
16 p[i]=p[i-1].multiply(multi);
17 }
18 }
19 public static void circle(int i)
20 {
21 int x=i;
22 while(a[i]!=x)
23 {
24 use[i]=true;i=a[i];
25 }
26 use[i]=true;
27 }
28 public static void main(String args[])
29 {
30 BigInteger nm;
31 Scanner cin=new Scanner(System.in);
32 n=cin.nextInt();
33 m=cin.nextInt();
34 make_biginteger();
35 BigInteger ans=new BigInteger("0");
36 if(n!=m)
37 nm=BigInteger.valueOf(2*n*m);
38 else nm=BigInteger.valueOf(4*n*m);
39 int i,j,r,q;
40 int x,y,res;
41 for(r=0;r<n;r++)
42 for(q=0;q<m;q++)
43 {
44 res=0;
45 for(i=1;i<=n;i++)
46 for(j=1;j<=m;j++)
47 {
48 x=(i-1)*m+j;
49 y=((r+i-1)%n)*m+(q+j-1)%m+1;
50 a[x]=y;
51 }
52 for(i=1;i<=n*m;i++) use[i]=false;
53 for(i=1;i<=n*m;i++)
54 if(!use[i])
55 {
56 circle(i);
57 res++;
58 }
59 ans=ans.add(p[res]);
60
61 res=0;
62 for(i=1;i<=n;i++)
63 for(j=1;j<=m;j++)
64 {
65 x=(i-1)*m+j;
66 y=((2*n-r-i)%n)*m+(2*m-q-j)%m+1;
67 a[x]=y;
68 }
69 for(i=1;i<=n*m;i++) use[i]=false;
70 for(i=1;i<=n*m;i++)
71 if(!use[i])
72 {
73 circle(i);
74 res++;
75 }
76 ans=ans.add(p[res]);
77
78 if(n==m)
79 {
80 res=0;
81 for(i=1;i<=n;i++)
82 for(j=1;j<=m;j++)
83 {
84 x=(i-1)*m+j;
85 y=((q+j-1)%n)*m+(2*m-r-i)%m+1;
86 a[x]=y;
87 }
88 for(i=1;i<=n*m;i++) use[i]=false;
89 for(i=1;i<=n*m;i++)
90 if(!use[i])
91 {
92 circle(i);
93 res++;
94 }
95 ans=ans.add(p[res]);
96
97 res=0;
98 for(i=1;i<=n;i++)
99 for(j=1;j<=m;j++)
100 {
101 x=(i-1)*m+j;
102 y=((2*n-q-j)%n)*m+(r+i-1)%m+1;
103 a[x]=y;
104 }
105 for(i=1;i<=n*m;i++) use[i]=false;
106 for(i=1;i<=n*m;i++)
107 if(!use[i])
108 {
109 circle(i);
110 res++;
111 }
112 ans=ans.add(p[res]);
113 }
114
115 }
116 ans=ans.divide(nm);
117 System.out.println(ans);
118 }
119 }



posted on 2012-03-19 21:09  myoi  阅读(529)  评论(0编辑  收藏  举报

导航