前言
本文章只包含题目+答案,没有详细的分析过程(仅为了个人的归纳复盘使用)
题目以及讲解是看B站的视频:2014年JavaB组题1(C++C组题1)武功秘籍_哔哩哔哩_bilibili
2014-Java省赛第一题——武功秘籍
答案:7
关于这题的tips:
这题不需要编程,只需要好好看懂题目的意思(要了解书的结构)
关于这题我的图解过程:(细心一点就不会出错)
2014-Java省赛第二题——切面条
答案:1025
关于这题的tips:
解决方法:归纳分析+需找规律
关于这题我的图解过程:
2014-Java省赛第三题——猜字母
//猜字母
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] a = new char[2014];
int index = 0;
for (int i = 0; i < 106; i++) {
for (int j = 0; j < 19; j++) {
a[index++] = (char)('a' + j);
}
}
//检验字符数组的正确性
// for (int i = 0; i < 2014; i++) {
// System.out.print(a[i]+" ");
// }
int len = 2014;
while(len!=1){
int k = 0;
for (int i = 1; i < len; i+=2) {
a[k++] = a[i];
}
len = k;
}
System.out.print(a[0]);
}
}
答案:q
关于这题的tips:
其实这题的思路和蓝桥杯B组2013年的真题第八题——幸运数的思路很像,都是将删去项变成往前挪,但是这题比较简单,只需要先把数组构造出来再用while循环一次一次地往前挪,最后取第一个位置的内容就可以了
2014-Java省赛第四题——大衍数列
//大衍数列
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 1; i < 100; i++) {
if(i%2==0){
System.out.println(i*i/2);
}else{
System.out.println((i*i-1)/2);
}
}
}
}
答案:i%2==0
关于这题的tips:
这题比较简单,只要知道偶数项的求法就可以了
2014-Java省赛第五题——圆周率
//圆周率
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
double x = 111;
for (int n = 10000; n >= 0; n--) {
int i = 2*n + 1;
x = 2+(i*i/x);
}
System.out.println(String.format("%.4f", 4/(x-1)));
}
}
答案:4/(x-1)
关于这题的tips:
按照for循环中的代码推算一遍就能直到当n=0时,x=2+(1/x),也就是说距离图中给的公式还多了一个1,所以要x-1,又因为4/π=x-1,所以π=4/(x-1)
2014-Java省赛第六题——奇怪的分式
//奇怪的分式
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int count = 0;
for (int a = 1; a < 10; a++) {
for (int b = 1; b < 10; b++) {
if(a==b) continue;
for (int c = 1; c < 10; c++) {
for (int d = 1; d < 10; d++) {
if(c==d) continue;
int gcd1 = gcd(a*c,b*d);
int gcd2 = gcd(a*10+c,b*10+d);
if(a*c/gcd1==(a*10+c)/gcd2&&b*d/gcd1==(b*10+d)/gcd2){
count++;
}
}
}
}
}
System.out.println(count);
}
private static int gcd(int a, int b) {
if(b==0) return a;
return gcd(b,a%b);
}
}
答案:14
计算最大公约数的写法(模板)
private static int gcd(int a, int b) {
if(b==0) return a;
return gcd(b,a%b);
}
关于这题的tips:
这题就是要知道最大公约数的写法,其他的都按照条件写就可以了
2014-Java省赛第七题——扑克序列
package cn.edu.fjjxu;
//扑克序列
import java.util.HashSet;
import java.util.Set;
public class Main07 {
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] a = {'A','A','2','2','3','3','4','4'};
f(a,0);
for(String s : set){
System.out.println(s);
}
}
//用set集合,去掉重复的数值
static Set<String> set = new HashSet<String>();
private static void f(char[] a, int k) {
if(k==a.length){
String s = new String(a);
if(check(s)){
// System.out.println(s);
set.add(s);
}
}
for (int i = k; i < a.length; i++) {
char t = a[k];
a[k] = a[i];
a[i] = t;
f(a,k+1);
t = a[k];
a[k] = a[i];
a[i] = t;
}
}
private static boolean check(String s) {
if(s.lastIndexOf('A')-s.indexOf('A')==2&&
s.lastIndexOf('2')-s.indexOf('2')==3&&
s.lastIndexOf('3')-s.indexOf('3')==4&&
s.lastIndexOf('4')-s.indexOf('4')==5)
return true;
return false;
}
}
答案:2342A3A4(取字典序小的那个)
关于全排列的框架,在蓝桥杯B组2013年的真题第九题——带分数中就有提到过,这里再重新列出来
全排列的写法(模板)(这里使用的是整数数组,其他类型的数组也都是换汤不换药)
static int[] arr = {1,2,3,4,5,6,7,8,9};
static int count;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
f(arr,0);
}
//确认某一个排列的第k位
private static void f(int[] arr,int k){
if(k==9){//全部确认
if(check(arr)){
count++;
}
print(arr);
}
//选定第k位
for(int i=k;i<arr.length;i++){
//将第i位和第k位交换
int t = arr[i];
arr[i] = arr[k];
arr[k] = t;
//移交下一位去确认k+1位
f(arr,k+1);
//回溯(换回来)——深搜(退回来的时候,应该将之前的状态都清空,所以应该换回来)
t = arr[i];
arr[i] = arr[k];
arr[k] = t;
}
}
private static void print(int[] arr2) {
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]);
}
System.out.println();
}
关于这题的tips:
要掌握indexOf()和lastindexOf()的用法,必要时也可以使用集合set
2014-Java省赛第八题——分糖果
import java.util.Scanner;
//分糖果
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int count = 0;
while(true){
int t = a[0];//头尾特殊值
for (int i = 0; i <= n-2; i++) {
a[i] -= a[i] / 2;//自己的糖果扣除一半
a[i] += a[i+1] /2;//从右手边得到他的一半
if((a[i]%2)==1){
count++;//补糖
a[i]++;
}
}
//倒数第一个小朋友
a[n-1] -= a[n-1]/2;
a[n-1] += t/2;//t是a[0]
if((a[n-1]%2)==1){
count++;
a[n-1]++;
}
if(check(a,n)){
System.out.println(count);
return;
}
}
}
//check方法检查每个值是否相同
private static boolean check(int[] a,int n) {
int t = a[0];
for (int i = 1; i < n; i++) {
if(a[i] != t) return false;
}
return true;
}
}
关于这题的tips:
这题要找到需要特殊处理的位置,是a[n-1],倒数第一个小朋友
判断是奇数项后进行计数补糖,然后写一个check()方法,比较整个数组的值是否都相等
2014-Java省赛第九题——地宫取宝
import java.util.Scanner;
//地宫取宝_深搜_计数
public class Main {
private static final int MOD = 1000000007;
static int[][]data;
private static int n;
private static int m;
private static int k;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
k = sc.nextInt();
data = new int[n][m];//n行m列
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
data[i][j] = sc.nextInt();
}
}
for (int i = 0; i < 51; i++) {
for (int j = 0; j < 51; j++) {
for (int l = 0; l < 14; l++) {
for (int o = 0; o < 14; o++) {
cache[i][j][l][o] = -1;
}
}
}
}
long ans = dfs(0,0,-1,0);
//max为什么要传-1,因为宝物有可能是0
System.out.println(ans);
}
//记忆型递归
static long[][][][] cache = new long[51][51][14][14];//数据规模
private static long dfs(int x, int y, int max, int cnt) {
if(cache[x][y][max+1][cnt]!=-1) return cache[x][y][max+1][cnt];//取缓存
if(x==n||y==m||cnt>k) return 0;//防御,也就是数组最容易出现的下标越界的问题,要写在最前面
int cur = data[x][y];
int ans = 0;
if(x==n-1&&y==m-1){
if(cnt==k||cnt==k-1&&cur>max) return 1;
}
if(cur>max){
ans += dfs(x,y+1,cur,cnt+1);
ans += dfs(x+1,y,cur,cnt+1);
}
ans += dfs(x,y+1,max,cnt);
ans += dfs(x+1,y,max,cnt);
cache[x][y][max+1][cnt] = ans % MOD;
return ans%MOD;
}
}
关于这题的tips:
以下是我自己复盘代码的时候写的笔记,我觉得这题可以试着自己看看代码理解一下
记忆型搜索:避免重复计算(关于这个知识,我也不是很了解,代码中有涉及到的地方大家可以自己去搜索学习一下)
2014-Java省赛第十题——矩阵翻硬币
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
import javax.script.Bindings;
//矩阵翻硬币
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
String n=sc.next();
String m=sc.next();
BigInteger ans1=BigSqrt(n);
BigInteger ans2=BigSqrt(m);
BigInteger ans=ans1.multiply(ans2);
System.out.println(ans);
}
private static BigInteger BigSqrt(String s) {
int mlen=s.length();//被开方数的长度
int len;//开方后的长度
BigInteger beSqrtNum=new BigInteger(s);//被开方数
BigInteger sqrtOfNum;//存储开放后的数
BigInteger sqrtOfNumMul;//开方数的平方
String sString;//存储sArray转化后的字符串
if(mlen%2==0)
len=mlen/2;
else
len=mlen/2+1;
char[] sArry=new char[len];
Arrays.fill(sArry, '0');
for (int pos = 0; pos < len; pos++) {
//从最高开始遍历数组,每一位都转化为开方数平方后刚好不大于被开方数的程度
for (char num = '1'; num <= '9'; num++) {
sArry[pos]=num;
sString=String.valueOf(sArry);
sqrtOfNum=new BigInteger(sString);
sqrtOfNumMul=sqrtOfNum.multiply(sqrtOfNum);
if (sqrtOfNumMul.compareTo(beSqrtNum)==1) {
sArry[pos]-=1;
break;
}
}
}
return new BigInteger(String.valueOf(sArry));
}
}
关于这题的tips:(按照视频写的解题流程 ps.这题更像在考数学)
总结
程序填空题(填结果)
01 武功秘籍:书的构造方式,思维题
02切面条:发现规律,思维题
03猜字母:数组中元素的挪动和挤压
程序填空题(填代码)
04大衍数列:考察奇偶数判断
05圆周率:细心,极限思维
程序填空题(填结果)
06 奇怪的分式:枚举abcd,分数运算,最大公约数
07扑克排序:带重复元素的全排列
编程题
08 分糖果:模拟
09地宫取宝:搜索->记忆型递归,因为子问题重复求解
10矩阵翻硬币:本质上是数学题;字符,字符串,BigInteger的互相转化
2014年前几题的题目会比较简单,但是编程题不太容易想出来