历届试题 矩阵翻硬币(大数开方)
2017-02-20 16:11
225 查看
历届试题 矩阵翻硬币
时间限制:1.0s 内存限制:256.0MB
问题描述
小明先把硬币摆成了一个 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次方)。
这个题最先是想着通过模拟翻硬币的那个过程做的,但是提交后数据量非常大只过了10%的数据,然后打印出翻硬币的情况,从中发现了规律。
最终,归结为n开方数*m的开方数即为最终输出的结果。燃鹅,n和m都是非常的数,这就涉及到大数开方的算法。
模拟翻硬币的过程代码:
找到规律后用n开方*m开方:
大数开方的算法:
时间限制:1.0s 内存限制:256.0MB
问题描述
小明先把硬币摆成了一个 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次方)。
这个题最先是想着通过模拟翻硬币的那个过程做的,但是提交后数据量非常大只过了10%的数据,然后打印出翻硬币的情况,从中发现了规律。
最终,归结为n开方数*m的开方数即为最终输出的结果。燃鹅,n和m都是非常的数,这就涉及到大数开方的算法。
模拟翻硬币的过程代码:
import java.util.Scanner; public class 矩阵翻硬币 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int m=sc.nextInt(); int count=getFan(n+1,m+1); System.out.println(count); } private static int getFan(int n,int m) { int[][] data=new int [m]; for (int i = 1; i < n+1; i++) { for (int j = 1; j < m+1; j++) { int x=i,y=j; for (int k = 1; k*x < n; k++) { for (int h = 1; h*y < m ; h++) { if(data[k*x][h*y]==0) data[k*x][h*y]=1; else data[k*x][h*y]=0; } } } } int count=0; for (int i = 1; i < n; i++) { for (int j = 1; j < m; j++) { System.out.print(data[i][j]+","); if(data[i][j]==1) count++; } System.out.println(); } return count; } }
找到规律后用n开方*m开方:
import java.math.BigInteger; import java.util.Scanner; public class 大数开方2 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); BigInteger n=sc.nextBigInteger(); BigInteger m=sc.nextBigInteger(); System.out.println(sqrt(n).multiply(sqrt(m))); } private static BigInteger sqrt(BigInteger n) { BigInteger a; BigInteger b; a=BigInteger.TEN.pow((int)n.toString().length()/2); b=n.divide(a); while(!(a.equals(b)||a.equals(b.add(new BigInteger("-1")))||b.equals(a.add(new BigInteger("-1"))))){ a=a.add(b).divide(new BigInteger("2"));//a=(a+b)/2 b=n.divide(a); } if (a.equals(b.add(new BigInteger("-1")))) { return a; } return b; } }
大数开方的算法:
import java.math.BigInteger; import java.util.Scanner; public class 大数开方3 { public static BigInteger getSqrt(BigInteger n){ BigInteger a,b; BigInteger cs=new BigInteger("2"); int len=n.toString().length(); a=BigInteger.TEN.pow(len/2); b=n.divide(a); int k=1; while(k==1){ if(a.equals(b)||a.equals(BigInteger.ONE.add(b))||b.equals(BigInteger.ONE.add(a))){ k=0; }else{ a=a.add(b).divide(cs); b=n.divide(a); } } return a; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(System.in); for (int i = 1; i < 20; i++) { BigInteger n=BigInteger.valueOf(i); System.out.println(i+"开方为:"+getSqrt(n)); } //BigInteger n=sc.nextBigInteger(); //System.out.println(getSqrt(n)); } }
相关文章推荐
- 蓝桥杯 历届试题 矩阵翻硬币(大数开方)
- 历届试题 矩阵翻硬币(大数开方)
- 历届试题 矩阵翻硬币 大数开方
- 历届试题 矩阵翻硬币 蓝桥杯 大数开方 大数相乘
- 蓝桥杯 历届试题 矩阵翻硬币 【大数 + 完全平方数 + 二分】
- 蓝桥杯-历届试题-矩阵翻硬币-大数
- 历届试题 矩阵翻硬币(数学题,大数开根)
- 历届试题 矩阵翻硬币
- 蓝桥杯 历届试题 矩阵翻硬币
- 历届试题 矩阵翻硬币
- 历届试题 矩阵翻硬币 (大整数)
- 蓝桥杯 历届试题 矩阵翻硬币
- 历届试题 矩阵翻硬币
- 蓝桥 PREV-34 历届试题 矩阵翻硬币 【高精度】
- 蓝桥杯 历届试题 矩阵翻硬币
- 【历届试题】矩阵翻硬币
- 蓝桥 PREV-34 历届试题 矩阵翻硬币
- 蓝桥杯 历届试题 矩阵翻硬币 By Assassin 模拟
- 蓝桥杯 历届试题 矩阵翻硬币
- 历届试题 矩阵翻硬币