
- public class Main {
- static int count = 0;
- public static void main(String[] args) {
- char[][] ch = {
- { 'U', 'D', 'D', 'L', 'U', 'U', 'L', 'R', 'U', 'L' },
- { 'U', 'U', 'R', 'L', 'L', 'L', 'R', 'R', 'R', 'U' },
- { 'R', 'R', 'U', 'U', 'R', 'L', 'D', 'L', 'R', 'D' },
- { 'R', 'U', 'D', 'D', 'D', 'D', 'U', 'U', 'U', 'U' },
- { 'U', 'R', 'U', 'D', 'L', 'L', 'R', 'R', 'U', 'U' },
- { 'D', 'U', 'R', 'L', 'R', 'L', 'D', 'L', 'R', 'L' },
- { 'U', 'L', 'L', 'U', 'R', 'L', 'L', 'R', 'D', 'U' },
- { 'R', 'D', 'L', 'U', 'L', 'L', 'R', 'D', 'D', 'D' },
- { 'U', 'U', 'D', 'D', 'U', 'D', 'U', 'D', 'L', 'L' },
- { 'U', 'L', 'R', 'D', 'L', 'U', 'U', 'R', 'R', 'R' }
- };
- for (int i = 0; i < ch.length; i++) {
- for (int j = 0; j < ch[i].length; j++) {
- dfs(i, j, ch);
- }
- }
- System.out.println(count);
-
- }
-
- public static void dfs(int x, int y, char[][] ch) {
- int m = ch.length;
- int n = ch[0].length;
-
- if (x < 0 || y < 0 || x > m - 1 || y > n - 1) {
- count++;
-
- return;
- }
- char flag = ch[x][y];
- if (ch[x][y]=='p') {
- return;
- }
- ch[x][y] = 'p';
- if (flag == 'U') {
- dfs(x-1, y, ch);
- }
- if (flag =='L') {
- dfs(x, y-1, ch);
- }
- if (flag=='D') {
- dfs(x+1, y, ch);
- }
- if (flag =='R') {
- dfs(x, y+1, ch);
- }
-
- ch[x][y] = flag;
- }
- }
总结:A组今年第一题就这么恶心,没做出来直接看题解,是道dfs,但是中间要检测是否走过,走过的直接退出,这里用了一个flag变量来标记,刚进来就记录原本的方向,然后赋值成P标识走过了,如果下次进来if成立为p就直接return,说明走过了,然后返回上一层把flag赋值回去(递归的时候每层的变量都是独立的 所以不存在下层的flag会吧上层覆盖,所以我们层都用自己的flag记录
观察如下的算式:
9213×85674=789314562
左边的乘数和被乘数正好用到了 11 ~ 99 的所有数字,每个 11 次。 而乘积恰好也是用到了 11 ~ 99 的所有数字,并且每个 11 次。
请你借助计算机的强大计算能力,找出满足如上要求的 99 数算式一共有多少个?
注意:
- import java.util.Scanner;
- // 1:无需package
- // 2: 类名必须Main, 不可修改
- import java.util.HashSet;
- //import java.util.Scanner;
- import java.util.Set;
-
- public class Main {
- private static int[] a = {1,2,3,4,5,6,7,8,9};
- private static int ans;
- public static void main(String[] args) {
- // Scanner scan = new Scanner(System.in);
- // f(0);
- // System.out.println(ans);
- System.out.println(3250/2);
- // scan.close();
- }
- private static void f(int k) {
- if(k == 9) {
- for (int i = 1; i < 9; i++) {
- check(i);
- }
- }
- for (int i = k; i < a.length; i++) {
- int t = a[i];
- a[i] = a[k];
- a[k] = t;
-
- f(k+1);
-
- t = a[i];
- a[i] = a[k];
- a[k] = t;
- }
-
- }
- private static void check(int len) {
- int num1 =0;
- int num2 = 0;
- int t = 1;
- for (int i = len-1; i >= 0; i--) {
- num1 += a[i]*t;
- t*=10;
- }
- t = 1;
- for (int i = a.length-1; i >= len; i--) {
- num2 += a[i]*t;
- t*=10;
- }
- int num3 = num1*num2;
-
- String str = num3+"";
- if(str.length()!=9)return;
- Set
set = new HashSet<>(); - for (int i = 0; i < str.length(); i++) {
- if (str.charAt(i)!='0') {
- set.add(str.charAt(i));
- }
-
- }
- if(set.size() == 9) {
- ans++;
- // System.out.printf("%d * %d == %d\n",num1,num2,num3);
- }
- }
- }
总结:全排列,但是这个check比较难 第一个for是前面的数字,第二个是后面的数,然后相乘为9位数字而且不重复,就能ans++(放到set里面看有没有重复)
由 A,B,C 这3个字母就可以组成许多串。 比如:"A","AB","ABC","ABA","AACBB" ....填空
现在,小明正在思考一个问题: 如果每个字母的个数有限定,能组成多少个已知长度的串呢?
他请好朋友来帮忙,很快得到了代码, 解决方案超级简单,然而最重要的部分却语焉不详。
- {
- // a个A,b个B,c个C 字母,能组成多少个不同的长度为n的串。
- static int f(int a, int b, int c, int n)
- {
- if(a<0 || b<0 || c<0) return 0;
- if(n==0) return 1;
-
- return ________________________________; //填空
- }
-
- public static void main(String[] args)
- {
- System.out.println(f(1,1,1,2));
- System.out.println(f(1,2,3,3));
- }
- }
答案:f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1)
总结:看到这种最后小于0的肯定是递归的递减,有3种情况,a减少,b减少,c减少然后把他们的数量相加就是各种情况的总和。
最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少。
比如:"abcdkkk" 和 "baabcdadabc", 可以找到的最长的公共子串是"abcd",所以最大公共子串长度为 4。下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
请分析该解法的思路,并补全划线部分缺失的代码。填空
- import java.util.Scanner;
- public class Main
- {
- static int f(String s1, String s2)
- {
- char[] c1 = s1.toCharArray();
- char[] c2 = s2.toCharArray();
-
- int[][] a = new int[c1.length+1][c2.length+1];
-
- int max = 0;
- for(int i=1; i
- if(c1[i-1]==c2[j-1]) {
- a[i][j] = __________________________;
- if(a[i][j] > max) max = a[i][j];
- }
- }
- }
-
- return max;
- }
-
- public static void main(String[] args){
- int n = f("abcdkkk", "baabcdadabc");
- System.out.println(n);
- System.out.println(f("aaakkkabababa", "baabababcdadabc"));
- System.out.println(f("abccbaacbcca", "ccccbbbbbaaaa"));
- System.out.println(f("abcd", "xyz"));
- System.out.println(f("ab", "ab"));
-
- }
- }
答案:a[i-1][j-1]+1
总结:这题是动态规划,新的东西用到旧的,根据题大概可以理解到他是竖着遍历第一个字符串,横着遍历第二个,连续相等的话是斜着加的。从而可以推出当元素连续相等的时候,后面右下角的等于右上角元素加1。

5、购物单
小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。
这不,大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。
小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。
现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。
取款机只能提供 100100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。
以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。
- **** 180.90 88折
- **** 10.25 65折
- **** 56.14 9折
- **** 104.65 9折
- **** 100.30 88折
- **** 297.15 半价
- **** 26.75 65折
- **** 130.62 半价
- **** 240.28 58折
- **** 270.62 8折
- **** 115.87 88折
- **** 247.34 95折
- **** 73.21 9折
- **** 101.00 半价
- **** 79.54 半价
- **** 278.44 7折
- **** 199.26 半价
- **** 12.97 9折
- **** 166.30 78折
- **** 125.50 58折
- **** 84.98 9折
- **** 113.35 68折
- **** 166.57 半价
- **** 42.56 9折
- **** 81.90 95折
- **** 131.78 8折
- **** 255.89 78折
- **** 109.17 9折
- **** 146.69 68折
- **** 139.33 65折
- **** 141.16 78折
- **** 154.74 8折
- **** 59.42 8折
- **** 85.44 68折
- **** 293.70 88折
- **** 261.79 65折
- **** 11.30 88折
- **** 268.27 58折
- **** 128.29 88折
- **** 251.03 8折
- **** 208.39 75折
- **** 128.88 75折
- **** 62.06 9折
- **** 225.87 75折
- **** 12.89 75折
- **** 34.28 75折
- **** 62.16 58折
- **** 129.12 半价
- **** 218.37 半价
- **** 289.69 8折
需要说明的是,8888 折指的是按标价的 88%88 计算,而 88 折是按 80%80 计算,余者类推。 特别地,半价是按 50%50 计算。
请输出小明要从取款机上提取的金额,单位是元。
题解:这题考得就是excel的使用,我们直接算太慢了,最快的就是用excel表格。
6、纸牌三角形
A,2,3,4,5,6,7,8,9 共 99 张纸牌排成一个正三角形(AA 按 11 计算)。要求每个边的和相等。 下图就是一种排法。

这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
- import java.util.Scanner;
- // 1:无需package
- // 2: 类名必须Main, 不可修改
-
- public class Main {
- static int ans =0;
- static int[] a = {1,2,3,4,5,6,7,8,9};
- public static void main(String[] args) {
- Scanner scan = new Scanner(System.in);
- //在此输入您的代码...
- fun(0);
- System.out.println(ans/6);
- scan.close();
- }
- static void fun(int start)
- {
- if(start==a.length){
- if(check()){
- ans++;
- }
- }
- for(int i =start;i
- int temp = a[start];
- a[start] = a[i];
- a[i] = temp;
- fun(start+1);
- temp = a[start];
- a[start] = a[i];
- a[i] = temp;
- }
- }
- static boolean check()
- {
- int x1 =a[0]+a[1]+a[2]+a[3];
- int x2 =a[3]+a[4]+a[5]+a[6];
- int x3 =a[6]+a[7]+a[8]+a[0];
- if(x1==x2&&x2==x3)
- {
- return true;
- }
- return false;
- }
- }
总结:全排列。固定模板,但是有坑,他旋转和对称都算一种,那么对称要除2,旋转又有3种情况,所有ans一共要除以6
7、取位数
求1个整数的第k位数字有很多种方法。 以下的方法就是一种。填空
- import java.util.*;
- public class Main
- {
- static int len(int x){
- if(x<10) return 1;
- return len(x/10)+1;
- }
-
- // 取x的第k位数字
- static int f(int x, int k){
- if(len(x)-k==0) return x%10;
- return ______________________; //填空
- }
-
- public static void main(String[] args)
- {
- int x = 23513;
- //System.out.println(len(x));
- System.out.println(f(x,3));
- System.out.println(f(893275,2));
- }
- }
答案:f(x/10,k)
总结:当len(x)-k==0才return,大概率递归,递归要满足这个条件只能len减小或k变大,k是固定的,所以只能len(x)减小了,所以每次减小x/10,k不变
8、分巧克力
儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有 NN 块巧克力,其中第 ii 块是 H_i \times WiHi×Wi 的方格组成的长方形。为了公平起见,
小明需要从这 NN 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:
-
形状是正方形,边长是整数;
-
大小相同;
例如一块 6x5 的巧克力可以切出 6 块 2x2 的巧克力或者 2 块 3x3 的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
输入描述
第一行包含两个整数 N,KN,K (1 \leq N, K \leq 10^51≤N,K≤105)。
以下 N 行每行包含两个整数 H_i,W_iHi,Wi (1 \leq H_i, W_i \leq 10^51≤Hi,Wi≤105)。
输入保证每位小朋友至少能获得一块 1x1 的巧克力。
输出描述
输出切出的正方形巧克力最大可能的边长。
输入输出样例
输入
- 2 10
- 6 5
- 5 6
输出
2
- public class Main {
- public static void main(String[] args) {
- Scanner scan = new Scanner(System.in);
- int n = scan.nextInt();
- int k = scan.nextInt();
- int[][] nums = new int[n][2];
-
- for (int i = 0; i < n; i++) {
- nums[i][0]= scan.nextInt();
- nums[i][1]= scan.nextInt();
- }
-
- int left = 1,right = 100000;
- while (left < right) {
- int mid = left + (right - left + 1) / 2;
- int count = 0;
- for (int i = 0; i < n; i++) {
- count+=(nums[i][0]/mid) * (nums[i][1]/mid);
- }
- if (count < k) {
- right = mid - 1;
- }else left = mid;
- }
- System.out.println(left);
- }
- }
总结:暴力枚举题,枚举切的边长,当最后切出来的块数大于等于人数,就返回。我们可以优化为二分查找。
9、杨辉三角
杨辉三角也叫帕斯卡三角,在很多数量关系中可以看到,十分重要。
- 第0行: 1
- 第1行: 1 1
- 第2行: 1 2 1
- 第3行: 1 3 3 1
- 第4行: 1 4 6 4 1
- ....
两边的元素都是1, 中间的元素是左上角的元素与右上角的元素和。
我们约定,行号,列号都从 0 计数。所以: 第 6 行的第 2 个元素是 15,第 3 个元素是 20。
直观地看,需要开辟一个二维数组,其实一维数组也可以胜任。 如下程序就是用一维数组“腾挪”的解法。填空
- import java.util.Scanner;
- public class Main
- {
- // 杨辉三角形的第row行第col列
- static long f(int row, int col){
- if(row<2) return 1;
- if(col==0) return 1;
- if(col==row) return 1;
-
- long[] a = new long[row+1];
- a[0]=1;
- a[1]=1;
-
- int p = 2;
-
- while(p<=row){
- a[p] = 1;
- for( _________________ ) a[q] = a[q] + a[q-1];
- p++;
- }
-
- return a[col];
- }
-
- public static void main(String[] args){
- System.out.println(f(6,2));
- System.out.println(f(6,3));
- System.out.println(f(40,20));
-
- }
- }
答案:int q=p-1;q>=1;q--
总结:从上面可以看出来while循环是循环第几行,里面的for是为了遍历行内的元素,根据题目提示现在这个就是之前的a[q]+a[q-1],所以每次就是遍历这个q,我们要逆序遍历,为了不影响到下一次遍历
10、Excel地址
Excel 单元格的地址表示很有趣,它使用字母来表示列号。
比如,
A 表示第 1 列,
B 表示第 2 列,
Z 表示第 26 列,
AA 表示第 27 列,
AB 表示第 28 列,
BA 表示第 53 列,
当然 Excel 的最大列号是有限度的,所以转换起来不难。
如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?
本题目即是要求对输入的数字, 输出其对应的 Excel 地址表示方式。
输入描述
输入一个整数 nn,其范围 [1,2147483647]。
输出描述
输出 nn 对应的 Excel 地址表示方式。
输入输出样例
示例
输入
26
输出
Z
- public class Main {
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- int n=in.nextInt();
- String str="";
- for(int s;n!=0;n/=26){
- if(n%26==0) {
- n-=26;
- s=26;
- }else {
- s=n%26;
- }
- str=(char)(s+64)+str;
- }
- System.out.print(str);
- in.close();
- }
- }
总结:有点类似进制转换,循环每次都除26,除26前取余,然后记录余数,最后把他们字符串拼接起来,前面的余数在后面所以是str=(char)(s+64)+str; 其中如果除26==0就让s==26因为没有0这个对应的字母26就是z,然后n要减去26
11、日期问题
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入描述
一个日期,格式是 "AA/BB/CCAA/BB/CC" (0 \leq A, B, C \leq 90≤A,B,C≤9)。
输出描述
输出若干个不相同的日期,每个日期一行,格式是 "yyyy-MM-ddyyyy−MM−dd"。多个日期按从早到晚排列。
输入输出样例
示例
输入
02/03/04
输出
- 2002-03-04
- 2004-02-03
- 2004-03-02
- package saunfati;
-
- import java.text.SimpleDateFormat;
- import java.util.Scanner;
- import java.util.TreeSet;
-
- public class 日期问题 {
-
- public static void main(String[] args) {
- Scanner scanner = new Scanner(System.in);
- String temp = scanner.next();
- String date[] = temp.split("/");
- String y = date[0];
- String m = date[1];
- String d = date[2];
- String a = (Integer.parseInt(y)<60?"20"+y:"19"+y)+"-"+m+"-"+d;
- String b = (Integer.parseInt(d)<60?"20"+d:"19"+d)+"-"+y+"-"+m;
- String c = (Integer.parseInt(d)<60?"20"+d:"19"+d)+"-"+m+"-"+y;
-
- TreeSet
set = new TreeSet(); - if(f(a)) set.add(a);
- if(f(b)) set.add(b);
- if(f(c)) set.add(c);
- for(Object object:set) {
- System.out.println(object);
- }
- }
- static boolean f(String date) {
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- format.setLenient(false);
- try {
- format.parse(date);
- }catch(Exception e) {
- return false;
- }
- return true;
- }
-
- }
总结:本地可以用TreeSet来做到去重和排序。而且可以用SimpleDateFormat的setLenient方法来判断日期是否有效的。
-
相关阅读:
vue3实现表格的分页以及确认消息弹窗
服务器正文23:定时器设计与实现(8/7)
StarRocks 自增ID实现分页优化
Easyrecovery2022硬盘磁盘U盘免费数据恢复软件
PTE 口语练习准备(一)
郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许
文件夹重命名:解决文件夹名称难题,批量将中文翻译成英文
印刷行业APS解决方案
正则表达式学习笔记
基于QT实现的SSL协议的安全报文发送接收设计
-
原文地址:https://blog.csdn.net/weixin_54232666/article/details/127772330
-
最新文章
-
沪漂五周年了:我越来越迷茫了
Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
MySQL-Seconds_behind_master的精度误差
[MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
Agent OS :五种驯服不确定性的范式
PortSwigger SQL注入LAB11
数据库即时编译JIT
[Begin]AI Learn Data Day 0
深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU