标题:矩阵翻硬币

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

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

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

其中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;

对于100%的数据,n、m <= 10^1000(10的1000次方)。

资源约定:

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 2000ms

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

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。

解析:

方案一:

题目中提示:“聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。”

即假设所有格子硬币都是正面的,反向进行上述分析的模拟。

Scanner input = new Scanner(System.in);

int n = input.nextInt(); //硬币矩阵n行

int m = input.nextInt(); //硬币矩阵m列

int[][] arr = new int[n+1][m+1]; //定义硬币(数组大小+1的原因和题意相符,下标从1开始)

//将所有硬币变成正面(1:正面;0:反面)

for (int x = 1; x <= n; x++) {

for (int y = 1; y <= m; y++) {

arr[x][y] = 1;

}

}

//模拟Q操作

for (int x = 1; x <= n; x++) {

for (int y = 1; y <= m; y++) {

//循环行号和列好的倍数

for (int i = 1; i*x <= n; i++) {

for (int j = 1; j*y<=m; j++) {

int temp = arr[i*x][j*y];

arr[i*x][j*y] = temp==1?0:1;

}

}

}

}

int count = 0; //假设反面的数量为0

for (int x = 1; x <= n; x++) {

for (int y = 1; y <= m; y++) {

if(arr[x][y] == 0)

count++;

}

}

System.out.println(count);

由于题目有专门的描述如下:

【数据规模】

对于10%的数据,n、m <= 10^3;

对于20%的数据,n、m <= 10^7;

对于40%的数据,n、m <= 10^15;

对于100%的数据,n、m <= 10^1000(10的1000次方)。

资源约定:

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 2000ms

则表示此题对执行效率有一定的要求,而进行方案一进行模拟的形式,如果数据量大的情况下,效率低,不能完全满足题目的要求。

方案二:

假设硬币举证如下,模拟所有硬币Q操作翻转过程如下:

1 2 3

4 5 6

7 8 9

对第一个硬币Q操作,需要翻转硬币:1,2,3,4,5,6,7,8,9(即全部)

对第二个硬币Q操作,需要翻转硬币:2,5,8

对第三个硬币Q操作,需要翻转硬币:3,6,9

对第四个硬币Q操作,需要翻转硬币:4,5,6

对第五个硬币Q操作,需要翻转硬币:5

对第六个硬币Q操作,需要翻转硬币:6

对第七个硬币Q操作,需要翻转硬币:7,8,9

对第八个硬币Q操作,需要翻转硬币:8

对第九个硬币Q操作,需要翻转硬币:9

思路:

(1)每个硬币,如果知道被翻转了几次,则可以求出该硬币初始状态是正面还是反面,翻转了奇数次硬币初始为反面,翻转了偶数次硬币为正面。

(2)通过上述数据得出规律,翻转次数=行号的约数个数*列号的约数个数,即:

第一个硬币,行号为1(约数1,只有1个),列号为1(约数1,只有1个),翻转数量=1*1=1

第二个硬币,行号为1(约数1,只有1个),列号为2(约数1,2,有2个),翻转数量=1*2=2

第三个硬币,行号为1(约数1,只有1个),列号为3(约数1,3,有2个),翻转数量=1*2=2

第四个硬币,行号为2(约数1,2,有2个),列号为1(约数1,有1个),翻转数量=2*1=2

第五个硬币,行号为2(约数1,2,有2个),列号为2(约数1,2,有2个),翻转数量=2*2=4

第六个硬币,行号为2(约数1,2,有2个),列号为3(约数1,3,有2个),翻转数量=2*2=4

第七个硬币,行号为3(约数1,3,有2个),列号为1(约数1,有1个),翻转数量=2*1=2

第八个硬币,行号为3(约数1,3,有2个),列号为2(约数1,2,有2个),翻转数量=2*2=4

第九个硬币,行号为3(约数1,3,有2个),列号为3(约数1,3,有2个),翻转数量=2*2=4

(3)实际上不需要求行号和列号的约数个数,只需要确定约数个数是奇数还是偶数即可,如何确定某个数字的约数个数是奇数还是偶数,有规律:平方数的约数个数是奇数,其它数字的约数个数为偶数,例如:

4约数(1,2,4)有三个为奇数;9的约数(1,3,9)有三个为奇数;16约数(1,2,4,8,16)有5个为奇数

5约束(1,5)有两个为偶数;10约束(1,2,5,10)有四个为偶数;15约数(1,3,5,15)有四个为偶数

(4)翻转次数=行号的约数个数*列号的约数个数;并且(奇乘奇=奇,奇乘偶=偶,偶乘偶=偶),当结果为奇数时,初始状态才是反面,则要求行号约数个数和列号的约数个数都为奇数,则要求行号和列号都为平方数。

(5)即题目含义变成了求行号范围内有几个平方数,列号范围内有几个平方数,结果为两个数字的乘积。

(6)如果循环遍历行号和列号求含有平方数的个数,效率仍然很低下,有规律:某个数字内平方数的个数等于该数字的开方取整,例如:

9里面(1,4,9)三个平方数,9的开方也等于三;

20里面(1,4,9,16)四个平方数,20的开方然后取整等于四。

(7)我们得到结论:初始为反面的个数=行号的开方+列号的开方。

(8)由于行号和列号范围可以为(10的1000次方),直接用数字类型无法表示,无法使用Math.sqrt进行开方,只能将数字做为字符串进行处理。

(9)当数字字符串的长度为偶数,则开方结果的长度为(本身长度/2);当数字字符串的长度为奇数,则开方结果的长度为(本身长度/2+1),例如:

99长度为2,开方取整为9,长度为1;100长度为3,开方结果为10,长度为2;

(10)确定了开方长度之后,利用BigInteger和char[]数组,确定数组每一位数字求出开方结果。

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

String n = input.next(); //硬币矩阵n行

String m = input.next(); //硬币矩阵m列

BigInteger rowSqrt = sqrt(n);

BigInteger colSqrt = sqrt(m);

System.out.println(rowSqrt.multiply(colSqrt));

}

public static BigInteger sqrt(String s)

{

//数字字符串的长度为偶数,则开方结果的长度为(本身长度/2);

//当数字字符串的长度为奇数,则开方结果的长度为(本身长度/2+1)

int len = s.length() % 2 == 0 ? s.length()/2 : s.length()/2+1; //求开方之后的字符串长度

char[] arr = new char[len]; //定义字符数组用于存放开方后的字符串

Arrays.fill(arr,'0'); //将字符数组所有元素设置为'0'

BigInteger num = new BigInteger(s); //将字符串转成BigInteger类型

for (int i = 0; i < arr.length; i++)

{

//循环确定字符数组每一位的数字

for (char c = '0'; c <= '9'; c++)

{

arr[i] = c;

BigInteger sqrtNum = new BigInteger(String.valueOf(arr));

if(sqrtNum.pow(2).compareTo(num) == 1) //当前假设数字的平方超过了数字本身,则减1操作

{

arr[i] -= 1;

break;

}

}

}

return new BigInteger(String.valueOf(arr));

}

Java输出小明算对多少题目_2014年Java方向C组第十题相关推荐

  1. 山东科技大学OJ题库 1904 帮小明算算数

    1904 帮小明算算数 Description 小明现在正在学习加法,完成家庭作业后,经常需要借助计算机来验证自己做的答案是否正确.请帮小明写一个程序,辅助他进行验证答案. Input 输入只有一行, ...

  2. python:用三引号输出小明小张跑步图案

    输出小明小张跑步图案 相关说明 源码 运行结果 相关说明 python里用三引号输出多行的字符串,可以输出用一些符号排列而像其他物件的图像. 源码 ''' # coding=utf-8 # 输出小明小 ...

  3. java—猜猜小明的零花钱

    小明最近帮家里做了很多事情,妈妈很开心,打算给小明一些零花钱,但是在给钱之前,她想先和小明玩个游戏,猜猜零花钱有多少,猜中了才给,请用程序实现猜出零花钱到底有多少? import java.util. ...

  4. java输出x的值或无解,你所不知道的Java之Integer

    以下内容为作者辛苦原创,版权归作者所有,如转载演绎请在"光变"微信公众号留言申请,转载文章请在开始处显著标明出处. 实参形参 有些触发,之前也研究过Java的Integer,所以写 ...

  5. java输出两个整数的积_如何检查Java中的两个数字相乘是否会导致溢出?

    如何检查Java中的两个数字相乘是否会导致溢出? 我想处理两个数字相乘导致溢出的特殊情况. 代码看起来像这样: int a = 20; long b = 30; // if a or b are bi ...

  6. java变量小明扑克牌_算法练习篇之:扑克牌顺子

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 代码实现 import java.util.Arrays; public class isContinuous { //扑克牌顺子(必须连续的五个数字) ...

  7. 用java编程小明地铁_java实训地铁

    一.任务与目的 1.1任务 随着计算机技术的不断提高,计算机的发展也日渐成熟,它已进入人类社会的各个领域并发挥着越来越重要的作用.随着快节奏的生活,乘坐地铁已经成为非常实用的交通工具了,有很多优点安全 ...

  8. java 输出_使用IntelliJ IDEA2020.2.2 x64新建java项目并且输出Hello World

    作者:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! 知乎@极客小俊,官方首发原创文章 Bilibili: 极客小俊GeekerJun 第一步 ...

  9. java 输出ab_一道在知乎很火的 Java 题——如何输出 ab【转】

    这是一个源自知乎的话题,原贴链接:一道百度的面试题,有大神会嘛? 虽然我不是大神,但我也点进去看了一下,思考了一会之后有了一些思路,然后去看其它人的答案的时候果然全都已经被各路大神们先想到并贴出来了, ...

最新文章

  1. linux查找设备所在分片,Linux设备驱动统一模型解析
  2. 在日本山区流域使用支持向量机和 bagging、boosting 和 stacking 集成机器学习框架改进滑坡评估--文献阅读
  3. mysql 脚本安装工具_mysql 非安装版的一个自动安装脚本及工具(更新版)
  4. ffmpeg源码分析_ffmpeg音视频同步的几种策略
  5. 打开.pos文件--ProcessOn
  6. PreRNN+:Towards A Resolution of the Deep-in-Dilemma in Saptiotemporal Predictive Learning
  7. 团队作业四-WBS练习
  8. ODOO实现微信单点登入
  9. Altium Designer Query语句
  10. 博客阅读:图解Transformer(The Illustrated Transformer)
  11. 多多自走棋改动_《多多自走棋》9月底最新平衡性改了什么 最新平衡性改动介绍...
  12. 支付宝小程序状态栏显示图片
  13. @EnableConfigurationProperties 注解
  14. 北大计算机本科生如何保研清华,高考无缘清华、北大,选择这五所985大学,保研几率大...
  15. SPI通信拓扑如何选择?
  16. apsara clouder基础认证API接口
  17. 来自Percal25号行星的哥顿人
  18. 电子购物商城项目总结
  19. 2 仓储管理系统 门店端快速上手
  20. 非参数检验-Wilcoxon,Wilcoxon-Mann-Whitney符号秩检验以及Pearson,Spearman秩,Kendall τ相关检验(附带实例-R实现)

热门文章

  1. 全新的 Fragment 通信方式
  2. CSDN 开学见面礼!3 周带你 Get 大厂工程师基础能力
  3. Service Mesh微服务熔断、限流的骚操作
  4. 128核云原生新力作:Ampere® Altra® Max性能参数公布,提升50%!
  5. 当飞猪遇上 Serverless | 云原生 Talk
  6. 云计算风起云涌,超融合恰逢其时!
  7. 雷神开机logo更改_九代酷睿i9加持的性能怪兽 雷神911黑武士Ⅱ评测
  8. elasticsearch-7.15.2 集成pinyin分词器
  9. 使用IntelliJ IDEA 2019.3.2 x64 远程连接oracle数据库
  10. Cannot obtain primary key information from the database, generated objects may be incomplete