【思特奇杯.云上蓝桥-算法训练营】第2周

2024-04-07 01:48

本文主要是介绍【思特奇杯.云上蓝桥-算法训练营】第2周,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.带分数

100 可以表示为带分数的形式:100 = 3 + 69258 / 714

还可以表示为:100 = 82 + 3546 / 197

注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

类似这样的带分数,100 有 11 种表示法。

题目要求: 从标准输入读入一个正整数N (N<1000*1000) 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!

例如: 用户输入: 100 程序输出: 11

再例如: 用户输入: 105 程序输出: 6

利用回溯法,先将所有的可能列出1~9的排列,然后再根据加号和除号的位置筛选出所有的合适方案。

package com.test;import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;public class DaiFen {static LinkedList<Integer> paths = new LinkedList<Integer>();static int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };static int result = 0;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();dfs(paths, N);System.out.println(result);}public static void dfs(LinkedList<Integer> paths, int N) {if (paths.size() == 9) {accordWith(paths, N);return;}for (int i = 0; i < nums.length; i++) {if (paths.contains(nums[i])) {continue;}paths.add(nums[i]);dfs(paths, N);paths.removeLast();}}public static int calculateNumber(int start, int end) {int num = 0;for (int i = start; i <= end; i++) {num = num * 10 + paths.get(i);}return num;}public static void accordWith(List<Integer> list, int N) {for (int i = 0; i < 7; i++) {int intNum = calculateNumber(0, i);if (intNum >= N)break;for (int j = i + 1; j < 8; j++) {int child = calculateNumber(i + 1, j);int parent = calculateNumber(j + 1, 8);int temp = intNum + child / parent;if (child % parent == 0 && temp == N) {result++;}}}}}
2.李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。
像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

①回溯法,有两种选择。一个是遇到酒店,酒*2;一个是遇到花,酒-1。然后再筛选出最后是遇到花的情况的,即sum=1;

package com.test;public class LiBai {static int k, jiu = 2, hua = 0, dian = 0;public static void main(String[] args) {dfs(1);System.out.println(k);}private static void dfs(int n) {if (n == 15) {if (jiu == 1 && hua == 9 && dian == 5)k++;return;}for (int i = 1; i <= 2; i++) {//酒馆加酒if (i == 1) {jiu = jiu * 2;dian++;dfs(n + 1);jiu = jiu / 2;dian--;}//看花减酒if (i == 2) {jiu = jiu - 1;hua++;dfs(n + 1);jiu = jiu + 1;hua--;}}}}

②递归法
有两种情况选择,一种是遇到酒店*2,一种是遇到花+1;并且保证一种的次数是5 次,一种的次数是10次。终点是最后次数用尽,酒=0.

package com.test;public class LiBai2 {static int sum=0;public static void main(String[] args) {recur(5, 10, 2);System.out.println(sum);}public static void recur(int a,int b,int c) {if(a==0&&b==1&&c==1) {sum++;return;}//到酒馆if(a>0) recur(a-1, b, c*2);//到花if(b>0) recur(a, b-1, c-1);}
}
3.第39级台阶
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!站在台阶前,他突然又想着一个问题:如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?

①回溯算法

package com.test;public class Steps {static int count;static int sum;public static void main(String[] args) {dfs(0);System.out.println(sum);}public static void dfs(int steps) {if(steps>39) return;if (steps == 39) {if (count % 2 == 0) {sum++;}return;}for(int i=1;i<=2;i++) {count++;steps+=i;dfs(steps);steps-=i;count--;}}
}

② 递归算法

package com.test;public class Steps2 {static int sum=0;public static void main(String[] args) {recur(0, 0);System.out.println(sum);}public static void recur(int steps,int count) {if(steps>39) return;if(steps==39) {if(count%2==0) {sum++;return;}}recur(steps+1, count+1);recur(steps+2, count+1);}
}
4.穿越雷区

X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?

已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
在这里插入图片描述
思路:BFS算法

package com.test;import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;public class LeiQu {static int step = 0;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();String[][] strs = new String[n][n];Node start = new Node("A", 0, 0);Node end = new Node("B", 4, 0);Scanner scan2 = new Scanner(System.in);for (int i = 0; i < n; i++) {String line = scan2.nextLine();strs[i] = line.split(" ");}scan.close();scan2.close();DFS(start, end, strs);System.out.println(step);}public static int DFS(Node start, Node end, String[][] strs) {int p_x;int p_y;Queue<Node> queue = new LinkedList<>();Set<Node> visited = new HashSet<>();// 将起点加入到队列queue.add(start);visited.add(start);while (!queue.isEmpty()) {int size = queue.size();for (int i = 0; i < size; i++) {Node cur = queue.poll();if (end.equals(cur))return step;p_x = cur.x;p_y = cur.y;for (Node item : findAdj(p_x, p_y, strs)) {if (!visited.contains(item)) {if (!cur.val.equals(item.val)) {queue.offer(item);visited.add(item);}}}}step++;}return -1;}public static List<Node> findAdj(int x, int y, String[][] strs) {int n = strs[0].length;List<Node> list = new ArrayList<>();if (x + 1 < n) {list.add(new Node(strs[x + 1][y], x + 1, y));}if (y + 1 < n) {list.add(new Node(strs[x][y + 1], x, y + 1));}if (x - 1 >= 0) {list.add(new Node(strs[x - 1][y], x - 1, y));}if (y - 1 >= 0) {list.add(new Node(strs[x][y - 1], x, y - 1));}return list;}
}class Node {String val;int x;int y;public Node() {}public Node(String val) {this.val = val;}public Node(String val, int x, int y) {this.val = val;this.x = x;this.y = y;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((val == null) ? 0 : val.hashCode());result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Node other = (Node) obj;if (val == null) {if (other.val != null)return false;} else if (!val.equals(other.val))return false;if (x != other.x)return false;if (y != other.y)return false;return true;}}5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
10
5. 迷宫

【问题描述】

下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方。

010000
000100
001001
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。

对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。 请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt,内容与下面的文本相同)

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

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个字符串,包含四种字母 D、U、L、R,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

package com.test1;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Puzzle {public static void main(String[] args) {String str = "";try {str = "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";int[][] strToInt = new int[30][50];for (int i = 0; i < 30; i++) {for (int j = 0; j < 50; j++) {strToInt[i][j] = str.charAt(50 * i + j) - '0';}}Node start = new Node(0, 0, "", null);System.out.println(bfs(start, strToInt)); } catch (Exception e) {e.printStackTrace();}}public static String bfs(Node start, int[][] strToInt) {Queue<Node> queue = new LinkedList<Node>();int [][]visited=new int [30][50];queue.offer(start);visited[0][0]=1;while (!queue.isEmpty()) {int size = queue.size();Node cur = queue.poll();int p_x = cur.x;int p_y = cur.y;for (int i = 0; i < size; i++) {if (p_x == 49 && p_y == 29 && strToInt[cur.y][cur.x] == 0) {// 打印路径StringBuilder sb=new StringBuilder(cur.direct);while (cur.parentNode != null) {sb.append(cur.parentNode.direct);cur = cur.parentNode;}return sb.reverse().toString();}for (Node itemNode : findAdjNode(p_x, p_y, strToInt, queue)) {if (visited[itemNode.y][itemNode.x]!=1) {itemNode.parentNode = cur;queue.offer(itemNode);visited[itemNode.y][itemNode.x]=1;}}}}return null;}public static List<Node> findAdjNode(int x, int y, int[][] arr, Queue<Node> queue) {int ylen = arr.length;int xlen = arr[0].length;List<Node> list = new ArrayList<Node>();if (x + 1 < xlen && arr[y][x + 1] == 0) {list.add(new Node(x + 1, y, "R"));}if (x - 1 >= 0 && arr[y][x - 1] == 0) {list.add(new Node(x - 1, y, "L"));}if (y - 1 >= 0 && arr[y - 1][x] == 0) {list.add(new Node(x, y - 1, "U"));}if (y + 1 < ylen && arr[y + 1][x] == 0) {list.add(new Node(x, y + 1, "D"));}return list;}}class Node {int x;int y;String direct;Node parentNode;public Node() {super();}public Node(int x, int y, String direct) {super();this.x = x;this.y = y;this.direct = direct;}public Node(int x, int y, String direct, Node parentNode) {super();this.x = x;this.y = y;this.direct = direct;this.parentNode = parentNode;}}DDDDRRURRRRRRRDRRRDDDLDDRDDDDDDDDDDDDRDRDRRURRUURRDDDDRDRRRRRRURRDRRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDRDRRRRDRDRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
6.跳马问题

题目描述
中国象棋半张棋盘如图1所示。马自左下角(0,0)向右上角(m,n)跳。规定只能往右跳,不准往左跳。比如图1中所示为一种跳行路线,并将路径总数打印出来。

在这里插入图片描述
输入格式:

只有一行:两个数n,m

输出格式:

只有一个数:总方案数total。

package com.test1;import java.util.Scanner;public class TiaoMa {static int[][] options={{1,2},{2,1},{2,-1},{1,-2}};static int x=0; static int y=0;static int count=0;public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n = scanner.nextInt();int m=scanner.nextInt();dfs(0, 0,m,n);System.out.println(count);}public static void dfs(int x,int y,int m,int n) {if(x>m||y>n) return;if(y<0) return;if(x==m&&y==n) {count++;return;}for(int[] items:options) {x+=items[0];y+=items[1];dfs(x, y,m,n);x-=items[0];y-=items[1];}}
}4 8
37
7.路径之谜

小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。【如图1.png】所示。
按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 n 个靶子)
同一个方格只允许经过一次。但不必走完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图1.png中的例子。
在这里插入图片描述

package com.test1;
import java.util.Arrays;
import java.util.Scanner;  public class PathOfSecret {  static int N;    static int []north;//正北方靶数    static int []west;//正西方靶数    static int[][]direction={{0,-1},{0,1},{-1,0},{1,0}};//上下左右移动方向    static int[][]mark;//用来标记是否经过某块石头,0为未经过,1为经过    static int x,y;//石头坐标,正东方向为x轴正方向,正南方向为y轴正方向    public static void main(String[] args) {  Scanner console = new Scanner(System.in);  //地面有N*N个方格  N = console.nextInt();  //北边以及西边箭靶上的数字  north = new int[N];  west = new int[N];mark = new int[N][N];  for(int i = 0; i < N;i++){  north[i] = console.nextInt();  }  for(int i = 0; i < N; i++){  west[i] = console.nextInt();  }  mark[0][0]=1;  dfs("0");  }  public static void dfs(String s){  if(x==N-1&&y==N-1){  int[] north_count = new int[N];  int[] west_count = new int[N];  for(int i = 0; i < N;i++){  for(int j = 0; j < N; j++){  north_count[i] += mark[i][j];//每列靶子上的箭数  west_count[i] += mark[j][i];//每行靶子上的箭数  }  }if(Arrays.equals(north, north_count)&&Arrays.equals(west, west_count)){  System.out.println(s);  return;  }}  //朝四个方向走  for(int i = 0; i < 4; i++){  x += direction[i][0];  y += direction[i][1];  int position;  position = x+N*y;//石头编号  String str = s + " "+position;  if(x>=0 && y>=0 && x<N && y<N &&mark[x][y]==0){  mark[x][y]=1;  dfs(str);  mark[x][y]=0;}  x -= direction[i][0];  y-= direction[i][1];//回溯  }  }  }  

这篇关于【思特奇杯.云上蓝桥-算法训练营】第2周的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881351

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第