目录
一 阶乘数码
二 麦森数
三 模拟题
一 阶乘数码
本题中n<=1000,1000的阶乘为以下这么大,远超long的范围
402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
使用高精度计算,BigInteger可以表示任意大的数,仅受到内存的限制
数码就是一个数0-9
public class P1591 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int t = scanner.nextInt();
for (int i = 0; i < t; i++) {
int n = scanner.nextInt();
int a= scanner.nextInt();
BigInteger m=new BigInteger("1");
for (int j = 1; j <=n ; j++) {
m=m.multiply(new BigInteger(j+""));
}
System.out.println(m);
// 求sum中a的个数
String string = m.toString();
char[] chars = string.toCharArray();
int count=0;
for (char c : chars) {
if (c-'0'==a){
count++;
}
}
System.out.println(count);
}
}
}
使用高精度计算,BigInteger可以表示任意大的数,仅受到内存的限制
数码就是一个数0-9
public class P1591 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int t = scanner.nextInt();
for (int i = 0; i < t; i++) {
int n = scanner.nextInt();
int a= scanner.nextInt();
BigInteger m=new BigInteger("1");
for (int j = 1; j <=n ; j++) {
m=m.multiply(new BigInteger(j+""));
}
System.out.println(m);
// 求sum中a的个数
String string = m.toString();
char[] chars = string.toCharArray();
int count=0;
for (char c : chars) {
if (c-'0'==a){
count++;
}
}
System.out.println(count);
}
}
}
二 麦森数
求一个数的位数,我们可以根据数学公式直接计算,不需要知道该数具体的值
法一:使用数学公式计算位数
public static void main(String[] args) {
// 给一个数字P,求2的p次方-1 有多少位数字和最后500位
Scanner scanner=new Scanner(System.in);
int p=scanner.nextInt();
// 使用数学公式直接计算位数
int count= (int) ((Math.floor(p*Math.log10(2)))+1);
System.out.println(count);
// 直接算需要的后500位
BigInteger two=new BigInteger("2");
// 需要知道一个数的后n位,就对10的n次方取模
BigInteger mod=BigInteger.TEN.pow(500);
BigInteger last500=two.modPow(new BigInteger(p+""),mod).subtract(BigInteger.ONE);
String str=last500.toString();
if (str.length()<500){
// 高位补0
int diff=500-str.length();
StringBuilder stringBuilder=new StringBuilder(0);
for (int i = 0; i < diff; i++) {
stringBuilder.append("0");
}
str=stringBuilder+str;
}else{
str=str.substring(str.length()-500);
}
// 每行输出50位 输出10行
for (int i = 0; i < 10; i++) {
System.out.println(str.substring(i*50,i*50+50));
}
scanner.close();
}
法二:快速幂计算值,得出该数的位数
public static void main(String[] args) {
// 给一个数字P,求2的p次方-1 有多少位数字和最后500位
Scanner scanner=new Scanner(System.in);
int p=scanner.nextInt();
BigInteger result;
// 快速幂
result= quickMi(p);
result=result.subtract(new BigInteger("1"));
String str=result.toString();
System.out.println(str.length());
if (str.length()<500){
// 高位补0
int diff=500-str.length();
StringBuilder stringBuilder=new StringBuilder(0);
for (int i = 0; i < diff; i++) {
stringBuilder.append("0");
}
str=stringBuilder+str;
}else{
str=str.substring(str.length()-500);
}
// 每行输出50位 输出10行
for (int i = 0; i < 10; i++) {
System.out.println(str.substring(i*50,i*50+50));
}
}
private static BigInteger quickMi(int p) {
BigInteger base = new BigInteger("2");
BigInteger result = BigInteger.ONE;
while (p > 0) {
if (p % 2 == 1) {
result = result.multiply(base);
}
base = base.multiply(base); // 平方
p /= 2; // 指数除以2
}
return result;
}
private static BigInteger quickMi(int p) {
if (p==1){
return new BigInteger("2");
}
if (p%2==0){
// p位偶数
BigInteger sum=quickMi(p/2);
return sum.multiply(sum);
}else{
// p为奇数
BigInteger sum=quickMi(p/2);
return sum.multiply(sum).multiply(new BigInteger("2"));
}
}
三 模拟题
思路:
- 根据给定x,y值找到中心点,然后将2r+1阶矩阵顺时针旋转或者逆时针旋转
1 2 3 8 5 1 3 7 11
5 6 7 顺时针旋转90° -> 9 6 2 逆时针旋转90° -> 2 6 9
8 9 11 11 7 3 1 5 8
顺时针旋转:将某一列的值放到对应的行上(例如将第一列赋值到第一行),从下到上
逆时针旋转:最后一列元素放到第一行上,从上到下
注:在赋值元素时,如果直接替换容易元素覆盖,可以使用一个临时数组存储原来的元素,然后将对应元素赋值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] array=new int[n+1][n+1];
// 初始化数组
int number=1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <=n ; j++) {
array[i][j]=number++;
}
}
// 改变 m 次矩阵
for (int i = 0; i < m; i++) {
int x = scanner.nextInt();
int y = scanner.nextInt();
int r = scanner.nextInt();
int z = scanner.nextInt();
int[][] temp = new int[n+1][n+1];
for (int j = x - r; j <= x + r; j++) {
for (int k = y - r; k <= y + r; k++) {
temp[j][k] = array[j][k];
}
}
if (z == 0) {
int x1 = x + r;
int y1 = y - r;
// 2.1 顺时针将行内元素反转
for (int j = x - r; j <= x + r; j++) {
for (int k = y - r; k <= y + r; k++) {
// 将一列元素赋值到array对应的一行上
array[j][k] = temp[x1][y1];
x1--;
}
x1 = x + r;
y1++;
}
} else {
int x1 = x - r;
int y1 = y + r;
// 逆时针
for (int j = x - r; j <= x + r; j++) {
for (int k = y - r; k <= y + r; k++) {
// 将一列元素赋值到array对应的一行上
array[j][k] = temp[x1][y1];
x1++;
}
x1 = x - r;
y1--;
}
}
}
for (int i = 1; i< array.length; i++) {
for (int j = 1; j < array.length; j++) {
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
}