目录
第 1 题:三角回文数
问题描述
答案提交
运行限制
代码:
第 2 题:数数
问题描述
答案提交
运行限制
代码:
第 3 题:倍数问题_同余定理_分情况讨论
题目描述
输入描述
输出描述
输入输出样例
运行限制
代码:
问题描述
对于正整数 n, 如果存在正整数 k 使得 n=1+2+3+⋯+k=k(k+1)/2, 则 n 称为三角数。例如, 66066 是一个三角数, 因为 66066=1+2+3+⋯+363 。
如果一个整数从左到右读出所有数位上的数字, 与从右到左读出所有数位 上的数字是一样的, 则称这个数为回文数。例如, 66066 是一个回文数, 8778 也是一个回文数。
如果一个整数 n 既是三角数又是回文数, 我们称它为三角回文数。例如 66066 是三角回文数。
请问, 第一个大于 20220514 的三角回文数是多少?
答案提交
这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
package 第十四届蓝桥杯三月真题刷题训练;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
/**
* @author yx
* @date 2023-03-10 8:28
*/
public class day7 {
static BufferedReader ins = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer in = new StreamTokenizer(ins);
static PrintWriter out= new PrintWriter(System.out);
public static void main(String[] args) {
for (int i = 20220515 ; ; i++) {
if(isHuiWen(i)&&isSanJ(i)){
System.out.println(i);
return;
}
}
}
static boolean isHuiWen(int n){
char[] arr=(n+"").toCharArray();
int l=0;
int r=arr.length-1;
while (l<=r){
if(arr[l]!=arr[r]){
return false;
}
l++;
r--;
}
return true;
}
static boolean isSanJ(int n){
// (k)*(k+1)=2n
// 直接取(k+1)*(k+1)=2n的k,能减少很多时间
int k=(int) Math.sqrt(2*n)-1;
while (k*(k+1)<=n*2){
if(k*(k+1)==n*2){
return true;
}
k++;
}
return false;
}
}
问题描述
任何一个大于 1 的正整数都能被分解为若干个质数相乘, 比如 28=2×2×7 被分解为了三个质数相乘。请问在区间 [2333333, 23333333] 中有多少个正整数 可以被分解为 12 个质数相乘?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
package 第十四届蓝桥杯三月真题刷题训练.day7;
import java.util.ArrayList;
/**
* @author yx
* @date 2023-03-10 8:48
*/
public class 数数 {
public static void main(String[] args) {
int ans=0;
for (int i = 2333333; i <= 23333333 ; i++) {
// System.out.println(i);
if(check(i)){
ans++;
}
}
System.out.println(ans);
}
static boolean check(int n){
int ans=0;
//只需要到sqrt(n)即可,因为如果有一个因数大于等于sqrt(n)
// 那么必定有一个因数小于等于sqrt(n)
for (int i = 2; i*i <= n ; i++) {
while (n%i==0){
/*
此时的i是从2开始的,n除掉的一定是质数,并且先从最小的质数开始除
如果有非质数因子k,那么该数的因子一定存在小于sqrt(k)的最小因子数j
这个j如果是质数,那么一定会在前面被当作除数除掉
从而保证了每一个因子都是质数,非质数的会被分解成质数因子给除掉
*/
n/=i;
//更新数据
ans++;
}
}
/*
比如最后的n为5的时候,n%i!=0
但是5也是这里面的一个质数
所以这个质因子5不能漏掉
*/
if(n>1)ans++;
if(ans==12){
return true;
}
return false;
}
}
分解并存储每一个不重复(set去重)的质因数的代码:
题目描述
众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。
输入描述
第一行包括 2 个正整数 n, K。
第二行 nn 个正整数,代表给定的 n 个数。
其中,1≤n ≤10^5, 1≤K ≤10^3,给定的 n 个数均不超过 10^8。
输出描述
输出一行一个整数代表所求的和。
输入输出样例
示例
输入
4 3 1 2 3 4
输出
9
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
解析全在代码注释里,详细到每一行代码!!!!
package 第十四届蓝桥杯三月真题刷题训练.day7;
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
/**
* @author yx
* @date 2023-03-10 10:16
*/
public class 倍数问题 {
static PrintWriter out =new PrintWriter(System.out);
static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer in=new StreamTokenizer(ins);
/**
* 输入
* in.nextToken()
* int a= (int)in.nval;
*
* 输出
* out.print();
* out.flush();
*/
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt();
int k=scanner.nextInt();
int[][] nums=new int[k][3];
for (int i = 0; i < n; i++) {
//因为需要三个数字,因此只需要维护每个余数对应的前三大的数即可
int temp=scanner.nextInt();
int yuShu=temp%k;
//一定要保证降序排序这样有利于我们取大的数,即nums[yuShu][0]>nums[yuShu][1]>nums[yuShu][2]
if(temp>nums[yuShu][0]){
//如果temp比nums[yuShu][0]还大,那么temp就是nums[yuShu][0]
//原来的nums[yuShu][0]变成第二大,原来的nums[yuShu][1]变成第三大
//原来的nums[yuShu][2]被舍弃
nums[yuShu][2]=nums[yuShu][1];
nums[yuShu][1]=nums[yuShu][0];
nums[yuShu][0]=temp;
}else if(temp>nums[yuShu][1]){
//如果此时的temp不是最大的,但是比nums[yuShu][1]大
//那么原来的nums[yuShu][0]还是最大的
//temp变成第二大的,即temp=nums[yuShu][1]
//原来的nums[yuShu][1]就变成第三大的了
//原来的nums[yuShu][2]被舍弃
nums[yuShu][2]=nums[yuShu][1];
nums[yuShu][1]=temp;
}else if(temp>nums[yuShu][2]){
//此时的temp小于前两大的数,大于nums[yuShu][2]
//那么temp就代替nums[yuShu][2]
//原来的nums[yuShu][2]被淘汰
nums[yuShu][2]=temp;
}
}
int x1,x2,x3;
int ans=0;
for (int i = 0; i < k; i++) {//遍历余数
x1=nums[i][0];
if(nums[i][0]!=0){
for (int j = i; j < k ; j++) {
if(j==i){//若x1,x2余数相同都为i,则x2取余数i对应的第二大的数
x2=nums[j][1];
}else {//x1,x2余数不同的情况,x2取余数j对应的最大的数
x2=nums[j][0];
}
if(x2!=0){//余数为j,对应的数字存在的情况,找第三个余数z对应的数字
int z=(k-(i+j)%k)%k;//这个自己手写一些即可,不懂的地方评论区或私信问
if(i!=j){//余数i和余数j不相同
if(z==i){//x3和x1对应的余数相同,那么x3就取余数i对应的第二大的数
x3=nums[i][1];
}else if(z==j){//x3和x2对应的余数相同,那么x3就取余数j对应的第二大的数
x3=nums[j][1];
}else {//x3的余数既不等于i也不等于j的情况,那么x3就取余数z对应的最大的数
x3=nums[z][0];
}
}else {//x1和x2余数相同的情况
if(z==i){//x1和x2和x3余数相同的情况,x3取余数为i的第三大的数
x3=nums[i][2];
}else {//x3和x1和x2余数不同,那么x3取余数为z对应的最大的数字
x3=nums[z][0];
}
}
if(x3!=0){//余数为z且对应的数字存在的情况
ans=Math.max(ans,(x1+x2+x3));
}
}
}
}
}
System.out.println(ans);
}
}