zoukankan      html  css  js  c++  java
  • 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 }



  • 相关阅读:
    python 检测mobileprovision证书的过期时间
    dynamodb 分区键排序键介绍
    dynamodb 基本操作
    Python 实现一个栈
    openstack阅读链接
    mongoengine文档
    机器学习链接
    mongoengine的使用
    Timer(让函数定时执行)
    线程,进程,IO多路复用,协程的代码
  • 原文地址:https://www.cnblogs.com/myoi/p/2406833.html
Copyright © 2011-2022 走看看