2015年第六届蓝桥杯Java程序设计本科B组决赛 铺瓷砖(编程大题)

2015年第六届蓝桥杯Java程序设计本科B组决赛个人题解汇总:

https://blog.csdn.net/daixinliangwyx/article/details/90051040

 

第六题

标题:铺瓷砖

交题测试地址:https://www.dotcpp.com/oj/problem1827.html

                                图1                                                            图2

为了让蓝桥杯竞赛更顺利的进行,主办方决定给竞赛的机房重新铺放瓷砖。机房可以看成一个n*m的矩形,而这次使用的瓷砖比较特别,有两种形状,如图1所示。在铺放瓷砖时,可以旋转。

主办方想知道,如果使用这两种瓷砖把机房铺满,有多少种方案。

【输入格式】
输入的第一行包含两个整数,分别表示机房两个方向的长度。

【输出格式】
输出一个整数,表示可行的方案数。这个数可能很大,请输出这个数除以65521的余数。

【样例输入1】
4 4
【样例输出1】
2
【样例说明1】
这两种方案如下【图2.png】所示:
 
【样例输入2】
2 6
【样例输出2】
4
【数据规模与约定】
对于20%的数据,1<=n, m<=5。
对于50%的数据,1<=n<=100,1<=m<=5。
对于100%的数据,1<=n<=10^15,1<=m<=6。
 
资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗  < 8000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。


解法:观察数据范围,n达到了10^15,如果直接从1开始逐项模拟到n肯定是会超时的, 因此尝试直接计算来获得结果,由于m非常小(最大只到6),就可以分别讨论m固定值的情况下n为多少来算得答案。分别列举几项小的图来得到小图的答案,大图可以由小图拼成,因此可以通过直接计算来得到大图的答案。(比如m=4,n=4时,ans=2,固定m=4的情况下,n=8时ans就是2*2,可以由两个4*4拼成,n=12时ans就是2*2*2,可以由三个4*4拼成...)

有几种小图应该注意一下:(m=6,n=5)

还有m=5,n=5的时候:这个角度上有2*2*2=8种,4个方向上的图互不一样所有总共应该是8*4=32种

应该还有一些其它小图没考虑周全,但国赛在即实在不想再纠结于画图了因此撂下,留给有缘人继续探索吧。

注意由于n很大,进行了幂运算的话应该用大数来存。

我的代码:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static long n, m;
    public static BigInteger sum, mod = BigInteger.valueOf(65521);
    public static void main(String[] args) {
        n = in.nextLong();
        m = in.nextLong();
        sum = BigInteger.ZERO;
        if (n == 1 || m == 1) {
            out.println("0");
            out.flush();
        } else if (m == 2) {
            if (n == 2 || n == 4) sum = BigInteger.ZERO;
            else {
                if (n % 3 == 0) sum = BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(3)), mod);
                if (n % 5 == 0) sum = sum.add(BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(5)), mod));
                if (n % 8 == 0 && n % 3 != 0 && n % 5 != 0) sum = BigInteger.valueOf(8).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(8)), mod);
            }
            out.println(sum);
            out.flush();
        } else if (m == 3){
            if (n % 2 == 0) sum = BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(2)), mod);
            out.println(sum);
            out.flush();
        } else if (m == 4) {
            if (n % 3 == 0) sum = sum.add(BigInteger.valueOf(4).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(3)), mod));
            else if (n % 4 == 0) sum = sum.add(BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(4)), mod));
            else if (n % 5 == 0) sum = sum.add(BigInteger.valueOf(4).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(5)), mod));
            out.println(sum);
            out.flush();
        } else if (m == 5) {
            if (n % 2 == 0) sum = sum.add(BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(2)), mod));
            if (n % 5 == 0) sum = sum.add(BigInteger.valueOf(32).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(5)), mod));
            out.println(sum);
            out.flush();
        } else if (m == 6){
            if (n % 2 == 0) sum = sum.add(BigInteger.valueOf(4).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(2)), mod));
            if (n % 5 == 0) sum = sum.add(BigInteger.valueOf(2).modPow(BigInteger.valueOf(n).divide(BigInteger.valueOf(5)), mod));
            out.println(sum);
            out.flush();
        }
        out.close();
    }
    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public Double nextDouble() {
            return Double.parseDouble(next());
        }
        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }
        public BigDecimal nextBigDecimal() {
            return new BigDecimal(next());
        }
    }
}

评测结果:20

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值