【思特奇杯.云上蓝桥-算法训练营】第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

相关文章

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]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯: