最近蓝桥杯出结果了,本人有幸拿到省赛一等奖前列,现在趁着五一有空,发一发个人题解,因为我们学校是线下竞赛,所以代码都在学校的比赛机,只能再根据记忆打一打,不容易,大家要是觉得有帮助就点个赞,哈哈,祝大家在接下来的国赛还有acm省赛取得好成绩。
A.星期计算
答案:
答案是7
很简单的签到题:20的22次方取模7,最后记得加上6就OK ,用(a*b)%c = ((a%c)*(b%c))%c
或者直接大数、高精度模拟也行,代码如下
package 蓝桥杯补题;
public class AAA {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int num = 20;
for(int i = 1;i<=22;i++) {
num = (num*num)%7;
}
System.out.println((6+num));//最后输出7
}
}
B、山
直接找2022 ---- 2022222022中的山的数目,记住题目说的不减、不增,所以3333也是山哦。
答案:
答案是3138
package 蓝桥杯补题;
import java.util.*;
public class BBB {
private static boolean ok(long num) {
String p = String.valueOf(num);
StringBuffer p1 = new StringBuffer(p);
StringBuffer p2 = p1.reverse();
if(!p.equals(p2.toString())) {//判断反转后,是不是相等
return false;
}
for(int i = 0;i<p.length()/2;i++) {//判断前半部分是不是非递减
if(p.charAt(i)>p.charAt(i+1)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
int ans = 0;
for(long i = 2022;i<=2022222022;i++) {
if(ok(i)) {
ans++;
}
}
System.out.println(ans);//3138
}
}
接下来从编程题开始,我会用Java的快输啦(觉得太长直接看main方法就好,希望大家不要嫌弃我的代码长,呜呜)。要是大伙有疑问可以看我这篇博客:Java基础之快速输出输入篇_stu_kk的博客-CSDN博客
C、字符统计
答案:
直接在输入时记录出现次数并找出最大的出现次数,最后遍历A-Z看看谁是最多次的输出就ok。
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class CCC {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
String p = Line();
int cnt[] = new int[10001];
for(int i = 0;i<p.length();i++) {
cnt[p.charAt(i)]++;
}
int maxn = -1000000;
for(int i = 'A' ;i <= 'Z';i++) {
maxn = Math.max(maxn, cnt[i]);
}
for(int i = 'A' ;i <= 'Z';i++) {
if(maxn == cnt[i]) {
pw.print((char)i);
}
}
pw.flush();
}
}
D、最少刷题数:
答案:
这题的难点应该是多个数相同时,单纯二分会出错。利用两个二分查找,找出类似C++的lower_bound,upper_bound,这样就可以解决有很多个相同的数时的情况。(代码不一定对,但是试了很多极端的样例,都没问题就交了,如果有错误,希望大伙指出来)
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class DDD {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
private static int findlow(int k,int arr[]) {
int l = 1;
int r = n;
while(l < r) {
int mid = (l+r)/2;
if(arr[mid] >= k) {
r = mid;
}
else {
l = mid+1;
}
}
return l;
}
private static int findhigh(int k,int arr[]) {
int l = 1;
int r = n;
while(l < r) {
int mid = (l+r+1)/2;
if(arr[mid] > k) {
r = mid-1;
}
else {
l = mid;
}
}
return r;
}
private static int n,m,mp[],search[];
public static void main(String[] args) {
// TODO 自动生成的方法存根
n = Int();
mp = new int[n+1];
search = new int[n+1];
for(int i = 1;i<=n;i++) {
int a = Int();
mp[i] = a;
search[i] = a;
}
Arrays.sort(mp,1,n+1);
for(int i = 1;i<=n;i++) {
int low = findlow(search[i],mp);
int high = findhigh(search[i],mp);
int big = n - high;
int small = low - 1;
if(big <= small) {
pw.print("0 ");
}
else {
if(high == low) {
int up = big - small;
pw.print((mp[low+up/2] - mp[low] + 1)+" ");
}
else {
int same = high - low;
if(same + small >= big) {
pw.print("1 ");
}
else {
int up = big - same - small;
pw.print((mp[high+up] - mp[high] + 1)+" ");
}
}
}
}
pw.flush();
}
}
E、求阶乘
答案:
(看着5->1 10->2 15->3还想有点规矩,但是10e18的数据量太大,推dp估计也是爆内存)只能暴力拿个30的分了,把时间留给后面。直接找出数中包含10和2和5的个数,当等于k时,输出答案。
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class EEE {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
private static int n;
public static void main(String[] args) {
// TODO 自动生成的方法存根
n = Int();
int cnt0 = 0;
int cnt2 = 0;
int cnt5 = 0;
for(long i = 1;i<=10e18;i++) {
long num = i;
while(num%10 == 0 && num!=0) {
cnt0++;
num/=10;
}
while(num%5 == 0 && num!=0) {
cnt5++;
num/=5;
}
while(num%2 == 0 && num!=0) {
cnt2++;
num/=2;
}
if(cnt0 + Math.min(cnt5, cnt2) == n) {
pw.println(i);
pw.flush();
break;
}
}
}
}
F、最大子矩阵:
答案:
没办法啥好的想法,只能又一次嘎嘎暴力了。
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class FFF {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
static int[][] arr;
public static void main(String[] args) {
int n = Int();
int m = Int();
arr=new int[n][m];
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
arr[i][j] = Int();
}
}
int limit = Int();
int maxn = Integer.MIN_VALUE;
for(int i=n;i>0;i--) {
for(int j=m;j>0;j--) { // i*j的矩阵
for(int x=0;x<=n-i;x++) {
for(int y=0;y<=m-j;y++) { //左上角坐标
int max = find_max(i,j,x,y);
int min = find_min(i,j,x,y);
if((max-min)<=limit) {
maxn = Math.max(maxn, i*j);
}
}
}
}
}
pw.println(maxn);
}
private static int find_min(int i, int j, int x, int y) {
// TODO //寻找最小值
int res = Integer.MAX_VALUE;
for(int n=x;n<x+i;n++) {
for(int m=y;m<y+j;m++) {
res = Math.min(res, arr[n][m]);
}
}
return res;
}
private static int find_max(int i, int j, int x, int y) {
// TODO 寻找最大值
int res = Integer.MIN_VALUE;
for(int n=x;n<x+i;n++) {
for(int m=y;m<y+j;m++) {
res = Math.max(res, arr[n][m]);
}
}
return res;
}
}
G、数组切分:
答案:
如何判断一段数组是否连续,那就是该数组内的最大值减去最小值等于数组长度减1,用dp[i],表示长度为i的情况。
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class GGG {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
private static int n,mod = 1000000007;
public static void main(String[] args) {
// TODO 自动生成的方法存根
n =Int();
int mp[] = new int[n+1];
int dp[] = new int[n+1];
for(int i = 1;i<=n;i++) {
mp[i] = Int();
}
dp[0] = 1;
for(int i = 1;i<=n;i++) {
int minn = mp[i];
int maxn = mp[i];
for(int j = i;j>=1;j--) {
minn = Math.min(minn, mp[j]);
maxn = Math.max(maxn, mp[j]);
if(i - j == maxn - minn) {
dp[i] = ( dp[i]+dp[j-1] )%mod;
}
}
}
pw.println(dp[n]);
pw.flush();
}
}
H、会议迷宫:
我的做法时定义个300*300的数组,然后从[150,150]这个点开始跑路,如果跑到就标记为true,那么他就是空格,其他地方为*,记录最小、大的x和最小、大的y,用来构答案的图。因为要保证墙的数量最少,所以用dfs让连接外界的墙只要没接触到空格就清空。 (我自己写的样例都过了,就这么写)
答案:
package 蓝桥杯补题;
import java.io.*;
import java.util.*;
public class HHH {
private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
private static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
private static class StopMsgException extends Exception{
}
private static int Int() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
private static double Dou() {
try {
st.nextToken();
}
catch (IOException e) {
e.printStackTrace();
}
return st.nval;
}
private static String Str() {
try {
st.nextToken();
}
catch(IOException e) {
e.printStackTrace();
}
return st.sval;
}
private static String Line() {
String p = "";
try {
p = bf.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return p;
}
private static long Lon() {
try {
st.nextToken();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return (long)st.nval;
}
private static void dfs(int x,int y) {
if(mp[x][y] == ' ') {
return ;
}
for(int i = 0;i<4;i++) {
int nx = x+xy[i][0];
int ny = y+xy[i][1];
if(nx<minx-2||nx > maxx+2|| ny<miny-2 || ny>maxy+2 || is[nx][ny]) {
return;
}
}
mp[x][y] = ' ';
for(int i = 0;i<4;i++) {
int nx = x+xy[i][0];
int ny = y+xy[i][1];
if(!(nx<minx-2||nx > maxx+2|| ny<miny-2 || ny>maxy+2 || is[nx][ny])) {
dfs(nx,ny);
}
}
}
private static int xy[][] = {{0,-1},{0,1},{1,0},{-1,0}};
private static char mp[][];
private static boolean is[][];
private static int n,minx,maxx,miny,maxy;;
public static void main(String[] args) {
// TODO 自动生成的方法存根
n = Integer.valueOf(Line());
String p = Line();
int strx = 150;
int stry = 150;
mp = new char[300][300];
is = new boolean[300][300];
for(char as[] : mp)
Arrays.fill(as, '*');
minx = miny = Integer.MAX_VALUE;
maxx = maxy = Integer.MIN_VALUE;
for(int i = 0;i<n;i++) {
if(p.charAt(i) == 'U') {
strx--;
}
else if(p.charAt(i) == 'D') {
strx++;
}
else if(p.charAt(i) == 'L') {
stry--;
}
else if(p.charAt(i) == 'R') {
stry++;
}
maxx = Math.max(maxx, strx);
minx = Math.min(minx, strx);
maxy = Math.max(maxy, stry);
miny = Math.min(miny, stry);
mp[strx][stry] = ' ';
is[strx][stry] = true;
}
for(int i = minx-1;i<=maxx+1;i++) {
for(int j = miny-1;j<=maxy+1;j++) {
if(i == minx-1 || i == maxx+1 || j == miny-1 || j == maxy+1) {
if(mp[i][j] == '*') {
dfs(i,j);
}
}
}
}
for(int i = minx-1;i<=maxx+1;i++) {
for(int j = miny-1;j<=maxy+1;j++) {
pw.print(mp[i][j]);
}
pw.println();
}
pw.flush();
}
}
I、红路灯:
难度大+最后没时间做了。
J、拉箱子:
难度大+最后没时间做了。