1. 程式人生 > >HDU 1812 Count the Tetris(Polya定理)

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種顏色塗色,問你總共有多少種不同 的塗色方案。

兩個方案相同當且僅當一個方案可以通過旋轉、反射變成另外一種方案

解析:

Burnside引理與Polya定理

百度百科

置換群與Pólya定理

我一開始沒有看到反射這個變換..一直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)));
			
		
		}
		
	}
}