HDOJ 1812 Count the Tetris

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1812

这道题我们要用到的是Pólya定理(如果不懂Pólya定理的同学,欢迎观看小编的另一篇博客)。

此题置换的方式一共有8种置换方式,大类可以分为两个大类:旋转和翻折。我们求出每一种置换方式的循环节个数就可以了。

1.旋转:

旋转0度(360度):每一个格子都是到自己的一个循环节,所以循环节个数为n*n

旋转90度(顺时针):

(1)如果n为偶数,那么每一个格子都可以旋转四次回到自己这里,所以循环个数为(n*n)/4

(2)如果n为奇数,那么除了正中间那个格子都和偶数时一样,但中间那个单独的格子也是一个循环节,所以循环节个数为:(n*n-1)/4+1

旋转90度(逆时针):同上偶数(n*n)/4 奇数为(n*n-1)/4+1

旋转180度:

(1)如果n为偶数,那么每一个格子都可以旋转两次回到自己这里,所以循环节个数为(n*n)/2

(2)如果n为奇数,那么除了正中间那个格子都和偶数时一样,但中间那个单独的格子也是一个循环节,所以循环节个数为:(n*n-1)/2+1

2.翻折:

沿着中心线翻折(两个方向):

(1)如果n为偶数,那么每一个格子都试翻折两次回到自己这里,所以循环节个数为(n*n)/2

(2)如果n为奇数,那么除了中间那一列的格子都和偶数时一样,但中间那列格子自己也会有个循环节,所以循环节的个数为:(n*n-n)/2+n

沿着对角线翻折(两个方向):除了对角线上的格子自己就是一个循环节,其他的格子都是每翻折两次回到自己这里,所以循环节就是(n*n-n)/2+n

有了这些循环节后,我们就可以直接套Pólya定理公式得到答案了。

PS.此题属于大数据。

import java.util.*;
import java.math.*;
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNext())
        {
            int n = input.nextInt();
            BigInteger c = input.nextBigInteger();
            BigInteger ans = BigInteger.ZERO;
            if(n%2 == 0)
            {
                ans = ans.add(c.pow(n*n));
                ans = ans.add(BigInteger.valueOf(2).multiply(c.pow(n*n/4)));
                ans = ans.add(BigInteger.valueOf(3).multiply(c.pow(n*n/2)));
                ans = ans.add(BigInteger.valueOf(2).multiply(c.pow((n*n-n)/2+n)));
            }
            else
            {
                ans = ans.add(c.pow(n*n));
                ans = ans.add(BigInteger.valueOf(2).multiply(c.pow((n*n-1)/4+1)));
                ans = ans.add(c.pow((n*n-1)/2+1));
                ans = ans.add(BigInteger.valueOf(4).multiply(c.pow((n*n-n)/2+n)));
            }
            ans = ans.divide(BigInteger.valueOf(8));
            System.out.println(ans);
        }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值