HDU 1812 Count the Tetris(Polya定理)
Count the Tetris
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3170 Accepted Submission(s): 878
Problem Description
話說就是因為這個遊戲,Lele已經變成一個名人,每當他一出現在公共場合,就有無數人找他簽名,挑戰。
為了防止引起社會的騷動,Lele決定還是乖乖呆在家裡。
在家很無聊,Lele可不想像其他人一樣每天沒事在家數錢玩,於是他就開始數棋盤。他想知道,一個有N×N個格子的正方形棋盤,每個格子可以用C種不同顏色來染色,一共可以得到多少種不同的棋盤。如果一個棋盤,經過任意旋轉,反射後變成另一個棋盤,這兩個棋盤就是屬於同一種棋盤。
比如當N=C=2的時候,有下面六種不同的棋盤
現在告訴你N和C,請你幫幫Lele算算,到底有多少種不同的棋盤
Input
本題目包含多組測試,請處理到檔案結束。
每組測試資料包含兩個正整數N和C(0<N,C,<31),分別表示棋盤的大小是N×N,用C種顏色來進行染色。
Output
對於每組測試,在一行裡輸出答案。
Sample Input
2 2
3 1
Sample Output
6
1
題意:
有一個n*n的方格,讓你用c種顏色塗色,問你總共有多少種不同 的塗色方案。
兩個方案相同當且僅當一個方案可以通過旋轉、反射變成另外一種方案
解析:
我一開始沒有看到反射這個變換..一直WA...
標準的polya定理問題。
旋轉只有 0,90,180,270度四種旋法。
旋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
反射有水平反射、垂直反射、45度對角反射和135度對角反射
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n,c;
while(sc.hasNext()){
n=sc.nextInt();
c=sc.nextInt();
//System.out.print(n);
if(n==1){
System.out.println(c);
continue;
}
BigInteger ans=BigInteger.ZERO;
BigInteger ji=BigInteger.valueOf(c);
if(n%2==1){
ans=ans.add(ji.pow(n*n));
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow((n+1)*(n/2)/2+1)));
ans=ans.add(ji.pow((n+1)*(n/2)+1));
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow((n*n-n)/2+n)));
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow((n*n-n)/2+n)));
}
else
{
ans=ans.add(ji.pow(n*n));
//System.out.println(ans);
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow((n)*(n/2)/2)));
//System.out.println(ans);
ans=ans.add(ji.pow((n)*(n/2)));
//System.out.println(ans);
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow(n*n/2)));
ans=ans.add(BigInteger.valueOf(2).multiply(ji.pow((n*n-n)/2+n)));
}
System.out.println(ans.divide(BigInteger.valueOf(8)));
}
}
}