标签:map arr set int res 蓝桥 ++ 2020 组省赛
蓝桥杯2020年第十一届javaB组省赛
A:门牌制作
思路:判断1-2020每个数有多少个2即可,代码很容易实现
答案:624
public class A门牌制作 {
public static void main(String[] args) {
int res = 0;
for (int i = 1; i <= 2020; i++) {
int j = i;
while (j > 0) {
if ((j % 10) == 2) { //判断个位是否为2
res++;
}
j /= 10;//将个位去掉继续判断
}
}
System.out.println(res);
}
}
B:寻找2020
思路:遍历每个位置,然后分三个方向去走
答案:16520
public class B寻找2020 {
public static void main(String[] args) throws FileNotFoundException {
int[][] arr = input();//读取文件操作
int res = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
//1.先拿到每一个元素
if (arr[i][j] == 0) continue;//如果是0就跳过
//2.如果是2就分三路去搜索
if (j + 3 < arr[i].length && arr[i][j+1] == 0 &&
arr[i][j+2] == 2 && arr[i][j+3] == 0) {
res++;
}//向右
if (i + 3 < arr.length && arr[i+1][j] == 0 &&
arr[i+2][j] == 2 && arr[i+3][j] == 0) {
res++;
}//向下
if (i + 3 < arr.length && j + 3 < arr[i].length &&
arr[i+1][j+1] == 0 && arr[i+2][j+2] == 2 && arr[i+3][j+3] == 0) {
res++;
}//向右下侧
}
}
System.out.println(res);
}
private static int[][] input() throws FileNotFoundException {
FileInputStream fis = new FileInputStream(new File("D:\\workspace_idea\\javaSenior\\leetcode\\2020.txt"));
Scanner sc = new Scanner(fis);
List<String> list = new ArrayList<>();
while (sc.hasNext()) {
String s = sc.nextLine();
list.add(s);
}
int[][] arr = new int[list.size()][list.get(0).length()];
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.get(i).length(); j++) {
arr[i][j] = list.get(i).charAt(j) - 48;
}
}
return arr;
}
}
C:蛇形填数
思路:
- 找规律可以发现,n行n列的元素=(2 * n - 1行1列的元素 + 1行2 * n - 1列的元素) / 2 ,所以题目转化为找到这两个位置的元素。
- 第一行和第一列的元素很有特点,比如第2行第1列的元素是1+2=3;第1行第3列的元素是1+2+3=6;依次类推。如果n是奇数,则1+2+…+n就是第1行第n列的元素;如果n是偶数,则1+2+…+n就是第n行第1列的元素;
- 所以本题找第39行第1列的数 和 第1行第39列的数,然后求中间数。第39行第1列的数就是第38行第1列的数+1,最终就是要求(1+2+…+38+1 + 1+2+…+39) / 2;
答案:761 在网上看到有推出的公式直接代入,我数学能力表示搞不定。。
public class C蛇形填数 {
public static void main(String[] args) {
int a = 0, b = 0;
for (int i = 1; i <= 38; i++) {
a += i;
b += i;
}
a += 39;
b += 1;
int res = (a + b) / 2;
System.out.println(res);
}
}
D:七段码
思路:
- 利用二维数组表示图,将每个数码管之间的连接关系记录下来。
- 将所有可能的发光组合全部都拿到,然后利用set加上排序起到去重的效果
- 然后根据关系图来判断是否符合要求
答案:80
public class D七段码 {
static Set<String> set = new HashSet<>();
public static void main(String[] args) {
int[][] map = new int[7][7];
init(map);//1.初始化七段码的关系图
//2.将所有开灯的组合放在set
for (int i = 1; i <= 7; i++) {
combination("abcdefg".toCharArray(),0, i);
}
//3.然后结合关系图判断是否符合要求
int res = check(map);
System.out.println(res);
}
private static int check(int[][] map) {
int res = 0;
for (String s : set) {
boolean flag1 = true;//表示s是否符合要求,符合要求表示s可以连通起来
//判断连通的操作,先选出一个字符c,加入set,然后每一轮遍历s,将所有与c连接的字符加入set,
// 直到有一轮没有任何字符加入set,就表示不连通;如果全部加入了,就表示连通
Set<Character> set = new HashSet<>();
set.add(s.charAt(0));
while (set.size() < s.length()) { //当全部加入了set,就表示连通,就退出循环
boolean flag2 = false;//表示这一轮是否有字符加入set
for (int i = 1; i < s.length(); i++) {
if (set.contains(s.charAt(i))) {
continue;
}
for (char c : set) {
if (map[s.charAt(i) - 97][c - 97] == 1) {
set.add(s.charAt(i));
flag2 = true;
break;
}
}
}
if (!flag2) {
flag1 = false;
break;
}
}
if (flag1) {
res++;
}
}
return res;
}
private static void combination(char[] c, int k, int n) {
if (k == n) {
String s = new String(c, 0, n);
//存放进去之前,将s按照字典序排序,为了将 ab ba 这种情况合并成同一种结果
char[] chars = s.toCharArray();
Arrays.sort(chars);
set.add(new String(chars));
}
for (int i = k; i < c.length; i++) {
swap(c, i, k);
combination(c, k+1, n);
swap(c, i, k);
}
}
private static void swap(char[] c, int i, int j) {
char temp = c[i];
c[i] = c[j];
c[j] = temp;
}
private static void init(int[][] map) {
for (int i = 1; i < map.length - 1; i++) {
map[i][i-1] = 1;
map[i][i+1] = 1;
map[i][i] = 1;
}
map[0][1] = 1; map[0][5] = 1; map[1][6] = 1;map[2][6] = 1;
map[4][6] = 1; map[5][0] = 1;map[6][1] = 1; map[6][2] = 1;
map[6][4] = 1; map[6][5] = 1;
}
}
E:排序
思路:
- 因为要求最短,所以可以先假设字符串完全逆序 如 cba这样,这样的字符串长度n和交换次数c的关系 c = n * (n - 1) / 2,其实就是求了 1 + 2 + … + n - 1。
- 找到正好比100次大的c,就是n=15时,c=105。
- 因为要字典序最小,所以就将第一个字符和c-100位置的字符交换位置即可
答案: jonmlkihgfedcba
public class E排序 {
public static void main(String[] args) {
int c = 0;
int n;
for (n = 1; n < 100; n++) {
c += n - 1;
if (c >= 100) {
break;
}
}
System.out.println("c = " + c);
System.out.println("b = " + n);
}
}
F:成绩分析
思路:直接比较就行了,比较简单
public class F成绩分析 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
double sum = 0;
int max = 0; int min = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
int num = sc.nextInt();
max = Math.max(max, num);
min = Math.min(min, num);
sum += num;
}
System.out.println("max = " + max);
System.out.println("min = " + min);
System.out.println("average = " + String.format("%.2f",sum / n));
}
}
G:单词分析
思路:也比较简单,使用Map或者数组,只要把每个字符出现的次数记录下来就行了。
public class G单词分析 {
public static void main(String[] args) {
int[] time = new int[26];//因为只有小写字母,所以26的长度就可以了
Scanner sc = new Scanner(System.in);
String s = sc.next();
for (int i = 0; i < s.length(); i++) {
time[s.charAt(i) - 97]++;
}
//找到出现最多的字符就行了
char c = s.charAt(0); int t = 0;
for (int i = 0; i < s.length(); i++) {
int tt = time[s.charAt(i) - 97];
if (tt > t) {
c = s.charAt(i);
t = tt;
}
}
System.out.println(c);
System.out.println(t);
}
}
H:数字三角形
思路:
- 定义一个二维数组dp, dp(i)(j)表示走到i,j位置可以加到的最大的值。
- 因为要求向左下和向右下的次数相差不能超过1,所以经过推导,当层数n是奇数时,最终加和操作只能走到(n)(n/2)位置;当n是偶数时,能走到(n)(n/2)和(n)(n/2+1)位置,结果取dp数组中两者较大值即可。
public class H数字三角形 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] dp = new int[n+1][n+1];//下标为0的区域不放元素,方便理解,也方便后面代码书写,否则-1下标很难处理
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i][j] = sc.nextInt();//用题目数据给数组赋值。
dp[i][j] += Math.max(dp[i-1][j], dp[i-1][j-1]);//dp操作,
//dp存的是加和操作到这的最大值,而[i][j]位置的最大值是它左上方和右上方的最大值递推过来的。
}
}
int res = (n & 1) == 1 ? dp[n][n/2+1] : Math.max(dp[n][n/2], dp[n][n/2+1]);
System.out.println(res);
}
}
I:子串分值和
思路:两层循环,使用set来动态获取不同字符的个数
public class I子串分值和 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
long res = 0;
for (int i = 0; i < s.length(); i++) {
Set<Character> set = new HashSet<>();//每一轮用一个set,每加一个元素,记录一次不同字符的个数
for (int j = i; j < s.length(); j++) {
set.add(s.charAt(i));
res += set.size();
}
}
System.out.println(res);
}
}
J:装饰珠
思路:
- 首先整理数据
- 猎人有6件装备,所以需要一个长度为6的数组存放装备。
- 每一个装备都有自己的N个装饰孔,这里可以选择封装成装备类,类里有一个长度为N整型数组存放每个装饰孔的等级。
- 装饰珠封装成类,属性有等级(int),上限数量(int),价值(int[],长度就是上限数量),共有M个装饰珠,外面定义一个数组存放即可。
- 遍历每个装备,因为总的价值不同装备之间并无牵连,所以只需要每个装备都是最高价值就能解决
- 遍历装备的每个孔,枚举出所有对装饰珠的选,结果放在一个长度为M的数组,表示对第i个装饰珠选择了几次;然后根据装饰珠类中的价值数组,算出价值。枚举得到最终结果。
暂时没做出来。。。
参考文章:
https://blog.csdn.net/qq_45566354/article/details/109142062
https://blog.csdn.net/qq_43652327/article/details/109138697
标签:map,arr,set,int,res,蓝桥,++,2020,组省赛
来源: https://blog.csdn.net/Mercycpp/article/details/115575241
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。