标签:
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1963 Accepted Submission(s): 529
标准的polya定理问题。Polya定理,公式:S=(C^M1+C^M2+...+C^Mn)/G
G是阶数,Mi是各阶循环节的个数。
旋转只有 0,90,180,270度三种旋法。
#include<cstdio> #include <cassert> #include<cstring> #include<algorithm> using namespace std; const int MOD=10000; const int B=10000; const int SIZEN=505; const int L=505; struct Mat{ int num[40][40]; void init(int n){ for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=i*n+j; } void change(int n){ int t_num[40][40]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) t_num[j][n-i-1]=num[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=t_num[i][j]; } void change1(int n){ int t_num[40][40]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) t_num[i][n-j-1]=num[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=t_num[i][j]; } void change2(int n){ int t_num[40][40]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) t_num[n-i-1][j]=num[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=t_num[i][j]; } void change3(int n){ int t_num[40][40]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) t_num[j][i]=num[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=t_num[i][j]; } void change4(int n){ int t_num[40][40]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) t_num[n-1-j][n-1-i]=num[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) num[i][j]=t_num[i][j]; } void output(int n){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++) printf("%d ",num[i][j]); printf("\n"); } } }; struct BigInteger { BigInteger(int number = 0) : length(!!number) { assert(0 <= number && number < B); memset(digit, 0, sizeof(digit)); digit[0] = number; } BigInteger normalize() { while (length && !digit[length - 1]) { length --; } return *this; } int operator[](int index) const { return digit[index]; } int& operator[](int index) { return digit[index]; } void output(){ printf("%d",digit[length-1]); for(int i=length-2;i>=0;i--) printf("%04d",digit[i]); printf("\n"); } int length, digit[L]; }; bool operator < (const BigInteger &a, const BigInteger &b) { if (a.length != b.length) { return a.length < b.length; } for (int i = 0; i < a.length; ++ i) { if (a[i] != b[i]) { return a[i] < b[i]; } } return false; } BigInteger operator + (const BigInteger &a, const BigInteger &b) { BigInteger c; c.length = std::max(a.length, b.length) + 1; for (int i = 0, delta = 0; i < c.length; ++ i) { delta += a[i] + b[i]; c[i] = delta % B; delta /= B; } return c.normalize(); } BigInteger operator - (const BigInteger &a, int b) { assert(0 <= b && b < B); BigInteger c; c.length = a.length; for (int i = 0, delta = -b; i < a.length; ++ i) { delta += a[i]; c[i] = delta; delta = 0; if (c[i] < 0) { c[i] += B; delta = -1; } } return c.normalize(); } BigInteger operator * (const BigInteger &a, const BigInteger &b) { BigInteger c; c.length = a.length + b.length; for (int i = 0; i < a.length; ++ i) { for (int j = 0, delta = 0; j <= b.length; ++ j) { delta += a[i] * b[j] + c[i + j]; c[i + j] = delta % B; delta /= B; } } return c.normalize(); } BigInteger operator / (const BigInteger &a, int b) { assert(0 <= b && b < B); BigInteger c; c.length = a.length; for (int i = c.length - 1, delta = 0; i >= 0; -- i) { delta = delta * B + a[i]; c[i] = delta / b; delta %= b; } return c.normalize(); } BigInteger operator ^(const BigInteger &a,int b){ BigInteger ret,ta; ret=1;ta=a; while(b){ if(b&1) ret=ret*ta; ta=ta*ta; b>>=1; } return ret; } Mat mat; BigInteger ret,tmp; bool vis[1005]; void dfs(int u,int n){ if(vis[u]) return; vis[u]=1; int x=u/n; int y=u%n; dfs(mat.num[x][y],n); } void solve(int n,int c){ ret=0; ret.normalize(); tmp=c; tmp.normalize(); if(n%2==0){ ret=ret+(tmp^(n*n)); ret=ret+(tmp^(n*n/4)); ret=ret+(tmp^(n*n/2)); ret=ret+(tmp^(n*n/4)); ret=ret+(tmp^(n*n/2))*2; ret=ret+(tmp^((n*n-n)/2+n))*2; } else{ ret=ret+(tmp^(n*n)); ret=ret+(tmp^(n*n-1)/4+1); ret=ret+(tmp^(n*n-1)/2+1); ret=ret+(tmp^(n*n-1)/4+1); ret=ret+(tmp^((n*n-n)/2+n))*2; ret=ret+(tmp^((n*n-n)/2+n))*2; } ret=ret/8; ret.output(); } int main() { int n,c; while(scanf("%d%d",&n,&c)!=EOF) solve(n,c); }
旋0度,则置换的轮换数为n*n
旋90度,n为偶数时,则置换的轮换数为n*n/4,n为奇数,则置换的轮换数为(n*n-1)/4+1
旋180度,n为偶数时,则置换的轮换数为n*n/2,n为奇数,则置换的轮换数为(n*n-1)/2+1
旋270度,n为偶数时,则置换的轮换数为n*n/4,n为奇数,则置换的轮换数为(n*n-1)/4+1
反射 沿对角反射两种,沿对边中点连线反射两种
n为偶数时,沿对边中点连线反射两种的置换轮换数为 n*n/2
沿对角反射两种的置换轮换数为 (n*n-n)/2+n
n为奇数时,沿对边中点连线反射两种的置换轮换数为 (n*n-n)/2+n
沿对角反射两种的置换轮换数为 (n*n-n)/2+n
代码:
标签:
原文地址:http://www.cnblogs.com/ruoju/p/5400785.html