hdu 1812

题目概述

一个N*N的棋盘,用C种颜色染色,其中将棋盘旋转后重合,沿中线对称,沿对角线对称的不重复计数,问一共多少种染色方案

时限

1000ms/3000ms

输入

每行两个整数N,C,输入到EOF为止

限制

1<=N,C<=30

输出

每行一个数,为所求染色方案数

样例输入

2 2
3 1
30 30

样例输出

6
1
320655918792067344519812003636174936042833134268573324773917290347588687195583228957681478991668111923702407658831752945563294531748541469620668824889067711874726866312058347438467661246388715694305613461331436880271971151648725980628811895543560805289647628359316951330416403383661240070590005929268290315984398017105289968558085794371861494786147758635495136464643814846486645602598173929069309466300544223502029291006048962250125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000181686832397051520946056308805604466407581978045474875359304082504155934507238826154311278029700058810684471274766758018118781558443619431822845272307989789502119217489434773675721830466291083197394510990672829006479672817871147951255843375000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056262926820812101010816099729989223477132666830078100287001870103720151397131864096813133382596914690275360750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

讨论

数论,polya定理,如果不太清楚polya定理是什么,最好先去看一下蓝白书,好的,没走的应该都知道polya定理是什么了,按题目所言,置换有这样几种,没动,旋转90度,旋转180度,旋转270度,中线对称,对角线对称,没动的情况很明显,有多少格就有多少循环,这样是 N2 个循环,1种置换,旋转90度,只要知道三个旋转都是一个方向的就可以,每个格和其旋转90度后的格重合,这样每个循环节长度都是4,一共是 N22 ,对吗?不对,N为奇数不对,因为中间的格自己算一个循环节,所以对奇数是 N214+1 ,也就是 N2+34 ,旋转270度时同理,这样共2种置换,旋转180度时循环节长度是2,偶数是 N22 ,奇数是 N212+1 ,即 N2+12 ,1种置换,中线对称时,偶数直接就是 N22 ,因为其循环节长度都是2,而奇数的中间部分循环节长度都只有1,这样是 N2N2+N ,即 N2+N2 ,这样的对称轴水平竖直各一根,这是2种置换,对角线时,奇偶都一样,因为对角线的格子循环节长度都是1,这样就都是 N2+N2 ,同样对角线有2根,这是2种循环,最后,按polya定理乘方,加和,取平均,就是结果了
实现层面上,数据规模不大,乘方不用自己写了,但另一方面也不难发现最终结果是相当的大,用java大数解决可以方便一些,不会?那就用c++大数模版吧

题解状态

780MS,14216K,938 B,Java

题解代码

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

static int N;
static BigInteger C;
public static void main(String[] args) throws Exception {
    //System.setOut(new PrintStream(new FileOutputStream("ij_cout.txt")));
    System.setIn(new FileInputStream("ij_cin.txt"));
    Scanner cin = new Scanner(new BufferedInputStream(System.in));

    while (cin.hasNext()) {
        N = cin.nextInt();
        C = cin.nextBigInteger();
        if (N % 2 == 1)
            System.out.println(C.pow((N * N + 3) / 4).multiply(BigInteger.valueOf(2)).add(C.pow((N * N + 1) / 2)).add(C.pow(N * N)).add(C.pow((N * N + N) / 2).multiply(BigInteger.valueOf(4))).divide(BigInteger.valueOf(8)));
        else
            System.out.println(C.pow(N * N / 4).multiply(BigInteger.valueOf(2)).add(C.pow(N * N / 2).multiply(BigInteger.valueOf(3))).add(C.pow(N * N)).add(C.pow((N * N + N) / 2).multiply(BigInteger.valueOf(2))).divide(BigInteger.valueOf(8)));
    }
}
}

EOF

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值