001 组队(暴力)
一、题目描述
作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容。 每位球员担任 1 号位至 5 号位时的评分如下表所示。
请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?
二、题解(枚举)
这题可以手算,也可以通过程序解决,这里给出代码
总体思路:
- 开数组
new int[5][20]
初始化数组存储表格数据 - 双层循环枚举每一个评分,前提是5个位置都不相同
- 最后就是比较本次的
maxScore
与上一次的maxScore
import java.util.Scanner;
/**
* @Author: Hoji
* @Description:
* @Date: 11/18/2019 9:46 PM
*/
public class Main{
public static void main(String[] args) {
int[][] score = new int[20][5];
int maxScores = 0;
calc(score, maxScores);
System.out.println(maxScores);
}
private static int calc(int[][] score, int maxScores) {
Scanner s = new Scanner(System.in);
for (int i = 0; i < 5; i++)
for (int j = 0; j < 20; j++)
score[i][j]= s.nextInt();
for (int i = 0; i < 20; i++)
for (int j = 0; j < 20; j++)
for (int k = 0; k < 20; k++)
for (int l = 0; l < 20; l++)
for (int m = 0; m < 20; m++)
//须知:比较符号的传递性
if((i!=j && i!=k && i!=l && i!=m) &&
(j!=k && j!=l && j!=m) &&
(k!=l && k!=m) &&
(l!=m))
maxScores = Math.max(score[i][0] + score[j][1] +
score[k][2] + score[l][3] + score[m][4], maxScores);
return maxScores;
}
}
002 不同子串(暴力)
一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成
的串。例如,字符串aaab
有非空子串a, b, aa, ab, aaa, aab, aaab
,一共 7 个。注意在计算时,只算本质不同的串的个数。
请问,字符串 0100110001010001 有多少个不同的非空子串?
题解
/**
* @Author: Hoji
* @Description:
* @Date: 11/18/2019 10:17 PM
*/
import java.util.HashSet;
public class Main{
public static void main(String[] args) {
System.out.println(calc("0100110001010001"));
}
private static int calc(String s) {
int len = s.length();
HashSet<String> set = new HashSet<>();
for (int i = 0; i < len; i++)
for (int j = 0; i < len; j++)
set.add(s.substring(i,j+1));
return set.size();
}
}
002 年号子串(C语言)
小明用字母A 对应数字1,B 对应2,以此类推,用Z 对应26。对于27
以上的数字,小明用两位或更长位的字符串来对应,例如AA 对应27,AB 对
应28,AZ 对应52,LQ 对应329。请问2019 对应的字符串是什么?
这题主要考察进制的转换,这题相当于 26 进制。可以对比十进制,对10取模(取余)得到数的个位数,对 %26 得到 2019 对应 26 进制的最后一位字符的26进制
/**
* @Author: Hoji(PAN先森)
* @Description:
* @Date: 11/22/2019 12:20 AM
* @个人博客:https://www.hoji.site
*/
public class Main{
public static void main(String[] args) {
char[] letters = new char[27];
letters[0]='A';
for (int i = 1; i < 27; ++i)
letters[i] = (char)(letters[i-1]+1);
StringBuilder ans=new StringBuilder("");
int year = 2019;
int t;
while(year>0) {
t=year%26;
ans.append(letters[t]);
year /= 26;
}
System.out.println(ans.reverse());
}
}
递归求解:先递归求出2019的对应26进制的第一位数字,比如十进制27对应的26进制的就是11(26^1 + 26^0),那么十进制的27对应的年号子串 == AA.
/**
* @Author: Hoji(PAN先森)
* @Description:
* @Date: 11/22/2019 12:20 AM
* @个人博客:https://www.hoji.site
*/
public class Main{
private static void solve(int i) {
if(i <= 0) return;
solve(i/26);
System.out.println((char)(i%26 + 64));
}
public static void main(String[] args) {
solve(2019);
}
}
答案:BYQ
003 数列求值(数学)
一、题目描述
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第4项开始,每项都是前3项的和。求第20190324 项的最后4 位数字。
二、题解
问题本质:问题的本质与求斐波拉契数列的问题相同
隐含条件:求最后4位数字的意思其实是:第20190324
项的数值肯定不止4位数,故不管前面的数的位数的多少,我们只把数的最后四位取出!
/**
* @Author: Hoji
* @Description:
* @Date: 11/18/2019 10:17 PM
* @MyBlog:https://www.hoji.site ,一个富集创作与分享的乐园
*/
public class Main {
public static void main(String[] args) {
int t0=5, t1=9, t2=17;
int t = 0;
for(int i=7; i<20190321; i++) {
t = (t0 + t1 + t2) % 10000;
t0 = t1; //指针向前移动
t1 = t2;
t2 = t;
}
System.out.println(t2); //4694
}
}
004 数的分解(暴力)
一、题目
把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包 含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如1000+1001+18
和1001+1000+18
被视为同一种。
二、题解
题目信息:
- 三个不同的正整数
- 三个数都不包含
2
和4
- 顺序相同,看做同一种
功能抽取:
- 三个不同的正整数:用三个
for
,每一个循环的初始值都是上有一个循环变量的值+1,以确保数的不一致 - 不包含
2
与4
,见check()
函数 - 与(1)是一个意思
/**
* @Author: Hoji
* @Date: 11/14/2019 8:36 PM
* @MyBlog:https://www.hoji.site ,一个富集创作与分享的乐园
*/
import java.util.HashSet;
import java.util.Set;
public class Main{
public static boolean check(int n) {
int g;
while (n > 0) {
g=t%10;
if(g == 2 || g == 4) return false;
n/=10;
}
return true;
}
public static void main(String[] args) {
int ans=0;
for (int i = 1; i < 2019; i++)
for (int j = i+1; j < 2019; j++)
for (int k = j+1; k < 2019; k++)
if(check(i) && check(j) && check(k))
if(i+j+k==2019) ++ans;
System.out.println(ans);
}
}
005 迷宫
一、题目描述
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一.
对于上面的迷宫,从入口开始,可以按 DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
二、题解
大致思路:
- 构造迷宫数组 -> maze.charAt(50 * i + j) - ‘0’; 表示每50次j循环换一行,减去字符 ‘0’,相当于减去 ‘0’ 的 ASCII 码,最后变成数字。
- 然后就是构造 BFS 思路咯,BFS 一般都是利用 Queue 的 FIFO 性质,这样就可以从一个扩展到一个面(一个 Node 出队时,将其D、L、R、U四个方向的结点入队,不断重复该过程,知道 queue 为空)
/**
* @Author: Hoji(PAN先森)
* @Description:
* @Date: 11/19/2019 10:17 PM
* @个人博客:https://www.hoji.site
*/
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
int[][] data = new int[30][50];
for (int i = 0; i < 30; i++)
for (int j = 0; j < 50; j++)
data[i][j] = maze.charAt(50 * i + j) - '0';
//字典序:D(x+1,y)、L(x, y-1)、R(x, y+1)、U(x+1, y)
int[][] dir = {
{1, 0}, //(0,0) (0,1) D
{0, -1}, //(1,0) (1,1) L
{0, 1}, //(2,0) (2,1) R
{-1,0}}; //(3,0) (3,1) U
boolean[][] isVisited = new boolean[30][50];
String[] direction = { "D", "L", "R","U"};
LinkedList<Node1> queue = new LinkedList<>();
int tx=0, ty=0;
isVisited[0][0]=true;
String s = "";
queue.offer(new Node(0,0,0,""));
while(!queue.isEmpty()) {
Node currNode = queue.poll();
if(currNode .x == 29 && currNode.y == 49)
System.out.println((currNode.ans)); //186
for (int i = 0; i < 4; i++) {
tx=currNode .x + dir[i][0];
ty=currNode .y + dir[i][1];
if (tx<0 || tx>=30 || ty<0 || ty>=50 || isVisited[tx][ty] || data[tx][ty]==1) {
continue;
}
s=direction[i];
isVisited[tx][ty]=true;
queue.offer(new Node(tx, ty, currNode .step+1, currNode .ans+s));
}
}
}
private static String maze =
"01010101001011001001010110010110100100001000101010"
+ "00001000100000101010010000100000001001100110100101"
+ "01111011010010001000001101001011100011000000010000"
+ "01000000001010100011010000101000001010101011001011"
+ "00011111000000101000010010100010100000101100000000"
+ "11001000110101000010101100011010011010101011110111"
+ "00011011010101001001001010000001000101001110000000"
+ "10100000101000100110101010111110011000010000111010"
+ "00111000001010100001100010000001000101001100001001"
+ "11000110100001110010001001010101010101010001101000"
+ "00010000100100000101001010101110100010101010000101"
+ "11100100101001001000010000010101010100100100010100"
+ "00000010000000101011001111010001100000101010100011"
+ "10101010011100001000011000010110011110110100001000"
+ "10101010100001101010100101000010100000111011101001"
+ "10000000101100010000101100101101001011100000000100"
+ "10101001000000010100100001000100000100011110101001"
+ "00101001010101101001010100011010101101110000110101"
+ "11001010000100001100000010100101000001000111000010"
+ "00001000110000110101101000000100101001001000011101"
+ "10100101000101000000001110110010110101101010100001"
+ "00101000010000110101010000100010001001000100010101"
+ "10100001000110010001000010101001010101011111010010"
+ "00000100101000000110010100101001000001000000000010"
+ "11010000001001110111001001000011101001011011101000"
+ "00000110100010001000100000001000011101000000110011"
+ "10101000101000100010001111100010101001010000001000"
+ "10000010100101001010110000000100101010001011101000"
+ "00111100001000010000000110111000000001000000001011"
+ "10000001100111010111010001000110111010101101111000";
}
class Node {
int x,y;
@Override
public String toString() {
return "Node{" +
"ans='" + ans + '\'' +
'}';
}
int step;
String ans;
Node(int x1, int y1, int step1, String ans1) {
x=x1; y=y1;
step = step1;
ans = ans1;
}
}
006 特别数的和
小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。 请问,在 1 到 n 中,所有这样的数的和是多少?
【样例输入】 40
【样例输出】 574
二、题解(暴力枚举)
这题算是比较简单的一题了,直接枚举[1~n]
中的每一位数字,如果数字中含有2 / 0 / 1 / 9其中之一,那么sum+=i
/**
* @Author: Hoji
* @Description:
* @Date: 11/19/2019 10:17 AM
*/
import java.util.Scanner;
public class B6_特别数的和 {
public static void main(String[] args) {
int n;
Scanner s = new Scanner(System.in);
try {
n = s.nextInt();
int sum=0;
String sn;
for (int i = 1; i <= n; i++) {
sn=i+"";
if(sn.indexOf("0") > -1||sn.indexOf("1") > -1 ||
sn.indexOf("2") > -1||sn.indexOf("9") > -1)
sum+=i;
}
System.out.println(sum);
}
catch (Exception e) {
s.close();
}
}
}
总结
题号 | 考察点 |
---|---|
001 组队 | 枚举 |
002 不同子串 | 枚举,HashSet |
003 年号子串 | 进制转换 |
004 数的分解 | 枚举 |
005 迷宫 | dfs |
006 特别数的和 | 枚举 |