算法笔记168:历届试题 矩阵翻硬币(Java)

目录

1 问题描述

2 解决方案

 


1 问题描述

问题描述

  小明先把硬币摆成了一个 n 行 m 列的矩阵。

  随后,小明对每一个硬币分别进行一次 Q 操作。

  对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转。

  其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。

  当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。

  小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。

  聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。

输入格式

  输入数据包含一行,两个正整数 n m,含义见题目描述。

输出格式

  输出一个正整数,表示最开始有多少枚硬币是反面朝上的。

样例输入

2 3

样例输出

1

数据规模和约定

  对于10%的数据,n、m <= 10^3;
  对于20%的数据,n、m <= 10^7;
  对于40%的数据,n、m <= 10^15;
  对于10%的数据,n、m <= 10^1000(10的1000次方)。


2 解决方案

具体代码如下:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static BigInteger getSqrt(String A) {
        String sqrt = "0";
        String pre = "0";
        BigInteger twenty = new BigInteger("20");
        BigInteger temp1 = BigInteger.ZERO;
        BigInteger temp2 = BigInteger.ZERO;
        int len = A.length();
        if(len % 2 == 1) {
            A = "0" + A;
            len = len + 1;
        }
        for(int i = 0;i < len / 2;i++) {
            BigInteger tempN = new BigInteger(pre + A.substring(i*2, i*2 + 2));
            for(int j = 0;j <= 9;j++) {
                BigInteger tempJ = new BigInteger(j+"");
                temp1 = twenty.multiply(new BigInteger(sqrt)).add(tempJ).multiply(tempJ);
                tempJ = tempJ.add(BigInteger.ONE);
                temp2 = twenty.multiply(new BigInteger(sqrt)).add(tempJ).multiply(tempJ);
                if(temp1.compareTo(tempN) <= 0 && temp2.compareTo(tempN) > 0) {
                    sqrt = sqrt + j;
                    pre = tempN.subtract(temp1).toString();
                    break;
                }
            }
        }
        return new BigInteger(sqrt);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String n = in.next();
        String m = in.next();
        BigInteger result = getSqrt(n).multiply(getSqrt(m));
        System.out.println(result);
    }
}
时间: 2024-11-03 01:29:59

算法笔记168:历届试题 矩阵翻硬币(Java)的相关文章

蓝桥 PREV-34 历届试题 矩阵翻硬币

历届试题 矩阵翻硬币 时间限制:1.0s   内存限制:256.0MB 问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转. 其中i和j为任意使操作可行的正整数,行号和列号都是从1开始. 当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹--所有硬币均为正面朝上. 小明想知道最开始有多少枚硬币是反面朝上的.于是,他向他的好朋友小M寻求帮助.

历届试题 矩阵翻硬币 (蓝桥杯)

历届试题 矩阵翻硬币 时间限制:1.0s   内存限制:256.0MB 问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转. 其中i和j为任意使操作可行的正整数,行号和列号都是从1开始. 当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上. 小明想知道最开始有多少枚硬币是反面朝上的.于是,他向他的好朋友小M寻求帮助.

算法笔记_176:历届试题 最大子阵(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大. 其中,A的子矩阵指在A中行和列均连续的一块. 输入格式 输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数. 接下来n行,每行m个整数,表示矩阵A. 输出格式 输出一行,包含一个整数,表示A中最大的子矩阵中的元素和. 样例输入 3 3-1 -4 33 4 -1-5 -2 8 样例输出 10 样例说明 取最后一列,和为10. 数据规模和约定 对于50

算法笔记_189:历届试题 横向打印二叉树(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 二叉树可以用于排序.其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树. 当遇到空子树时,则把该节点放入那个位置. 比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白. ...|-1210-|...|-8-|.......|...|-7.......|-5-|...........|-4 本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横

历届试题 矩阵翻硬币

问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转. 其中i和j为任意使操作可行的正整数,行号和列号都是从1开始. 当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹--所有硬币均为正面朝上. 小明想知道最开始有多少枚硬币是反面朝上的.于是,他向他的好朋友小M寻求帮助. 聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的

算法笔记_198:历届试题 打印十字图(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示: ..$$$$$$$$$$$$$....$...........$..$$$.$$$$$$$$$.$$$$...$.......$...$$.$$$.$$$$$.$$$.$$.$...$...$...$.$$.$.$$$.$.$$$.$.$$.$.$...$...$.$.$$.$.$.$$$$$.$.$.$$.$.$...$...$.$.$$.$.$$$.$.$$$.$.

算法笔记_182:历届试题 核桃的数量(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑).他的要求是: 1. 各组的核桃数量必须相同 2. 各组内必须能平分核桃(当然是不能打碎的) 3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛) 输入格式 输入包含三个正整数a, b, c,表示每个组正在加班的人数,用空格分开(a,b,c<30) 输出格式 输出一个正整数,表示每袋核桃的数量. 样例输入1 2 4 5

算法笔记_181:历届试题 回文数字(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的.这样的数字叫做:回文数字. 本题要求你找到一些5位或6位的十进制数字.满足如下要求: 该数字的各个数位之和等于输入的整数. 输入格式 一个正整数 n (10<n<100), 表示要求满足的数位和. 输出格式 若干行,每行包含一个满足要求的5位或6位整数. 数字按从小到大的顺序排列. 如果没有满足条件的,输出:-1 样例输入 44 样例输

算法笔记_185:历届试题 格子刷油漆(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但不能移动到较远的格子(因为油漆未干不能踩!) 比如:a d b c e f 就是合格的刷漆顺序. c e f d a b 是另一种合适的方案. 当已知 N 时,求总的方案数.当N较大时,结果会迅速增大,请把结果对 1000000007 (十亿零七) 取模.