11k 词
八数码问题题目描述在 3 x 3 的棋盘上,摆有八个棋子,每个棋子上标有 1 至 8 的某一数字。棋盘中留有一个空格,空格用 0 来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为 123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。 输入格式输入初始状态,一行九个数字。 输出格式只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数。保证测试数据中无特殊无法到达目标状态数据。 样例样例输入283104765 样例输出4 提示样例解释 图中标有 0 的是空格。绿色格子是空格所在位置,橙色格子是下一步可以移动到空格的位置。如图所示,用四步可以达到目标状态。 并且可以证明,不存在更优的策略。 BFS+康托判重首先介绍一个东西,叫做康托展开。 来自wikipedia:康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。 https://zh.wikipedia.org/wi...
28k 词
老周的运动题目描述老周最近几年日渐发福,因此决定运动起来。因为老周是程序员,喜欢有规律的运动。老周在三期操场上画出了坐标系,初始位置是(x,y)=(0,0)点 老周按照一定的规则进行跑步,面对坐标系上北下南左西右东。 起始时老周面朝东方,第i个阶段会向前走i米,并向左转。请计算老周经过n个阶段后的坐标。 输入格式一行一个整数 n,代表老周跑的阶段数。1<=n<=2*10^9 输出格式一行两个整数,表示老周n阶段后位置 x 和 y 坐标,中间一个空格分隔。 思考这个不是蓝桥真题,但是是之前天梯校队选拔赛的一道题,当时我记得我直接暴力模拟了。 import java.util.*; public class Main { public static void main(String[] a) { Scanner in = new Scanner(System.in); long n = in.nextLong(); long dir = 0L; lo...
8.6k 词
答疑题目描述有n位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下: 首先进入办公室,编号为 i的同学需要 si​ 毫秒的时间。 然后同学问问题老师解答,编号为 i 的同学需要 ai​ 毫秒的时间。 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可 以忽略。 最后同学收拾东西离开办公室,需要 ei​ 毫秒的时间。一般需要 10秒、20秒或 30秒,即 ei​ 取值为 10000,20000 或 30000一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。答疑从 0 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群 里面发消息的时刻之和最小。 输入描述输入第一行包含一个整数 n,表示同学的数量。接下来 n 行,描述每位同学的时间。其中第 i 行包含三个整数 si​,ai​,ei​,意义如上所述。其中有 1≤n≤1000,1≤si​≤60000,1≤ai​≤10^6,ei​∈10000,20000,30000,即 ei​ 一定是 10000、20000、30000...
11k 词
6.28实践学期编程比赛题目的思路以及题解 链接:http://acm.webvpn.neusoft.edu.cn/contest.php?cid=1439 放麦子题目描述你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第 1个棋盘格放 1 粒麦子,在第 2 个棋盘格放 2 粒麦子,在第 3个棋盘格放 4粒麦子,在第 4个棋盘格放 8 粒麦子,……后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有 64格)。 国王以为他只是想要一袋麦子而已,哈哈大笑。 当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用! 请你借助计算机准确地计算,到底需要多少粒麦子 思路这道题目的思路很简单,本质就是一个等比数列求和,首项为1,末项为2^63,公比为2,所以可以直接套用等比数列求和公式,即S = a1 * (1 - q^n) / (1 - q),其中a1为首项,q为公比,n为项数,即S = 1 * (1 - 2^64) / (1 - 2) = 2^64 - 1。 代码import java.math.BigInteger; ...
12k 词
小明和小强题目描述有两个自然数2<=x,y<=99,老师告诉小明两个数的和M,告诉小强两个数的积N。已知小明和小强都是超级无敌天才。 下面是两个人的对话: 小强:我不知道这两个数是多少,你肯定也不知道。 小明:本来我不知道,但你这么说我就知道了。 小强:那我也知道了。 问这两个数是多少? 思路根据哥德巴赫猜想:如果一个数是偶数,那么它可以分解为两个素数之和,而且两个素数之积是唯一的。也就是说,小明拿到的数一定不是偶数,否则小明就能知道这两个数了。 我们可以尝试枚举小明拿到的数M,然后枚举其中一个数x,用M-x得到另一个数y,如果x和y的积的拆分组合数量为1,小强是能知道这个数的,所以排除掉这种情况。 用一个函数f2来计算一个数的积的拆分组合数量,如果这个数的拆分组合数量为1,说明这个数是两个素数的积,否则不是。 // 用积拆分n的组合数量 public static int f2(int n) { int cnt = 0; for (int i = 2; i <= Math.sqrt(n); i++) { ...
11k 词
递归递归意味着“根据自身来定义问题”。这在编写算法方面可能是一个非常强大的工具。递归直接来自数学,其中有许多用自身编写的表达式的例子。例如,斐波那契数列定义为:F(i) = F(i-1) + F(i-2)。 用递归打印数字三角形我们需要打印以下的数字三角形: 1 22 333 4444 55555 ...... 定义函数f,唯一参数int n为行数,返回值为void。函数f的功能是打印一个数字三角形,其中第i行打印i个数字i。 public static void f(int n) { if (n == 0) return; f(n - 1); for (int i = 0; i < n; i++) { System.out.print(n); } System.out.println(); } 先想递归的终止条件,当n等于0时,不需要打印任何东西,直接返回。然后想如果我要打印n行的数字三角形,我可以先打印n-1行的数字三角形,然后再打印第n行。这样就可以用递归来解...
7.9k 词
题目花朵数一个 N 位的十进制正整数,如果它的每个位上的数字的 N 次方的和等于这个数本身,则称其为花朵数。 例如 当 N=3 时,153 就满足条件,因为 1^3 + 5^3 + 3^3 = 153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3 表示 5 的 3 次方,也就是立方)。 当 N=4 时,1634 满足条件,因为 1^4 + 6^4 + 3^4 + 4^4 = 1634。 当 N=5 时,92727 满足条件。 实际上,对 N 的每个取值,可能有多个数字满足条件。 程序的任务是:求 N=21 时,所有满足条件的花朵数。 注意:这个整数有 21 位,它的各个位数字的 21 次方之和正好等于这个数本身。 如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。要求程序在 1 分钟内运行完毕。 参考答案128468643043731391252 449177399146038697307 思路首先想到21位嘛,肯定不能暴力了,这个范围暴力效率太低了,而且的话涉及到高精度,比...
6.8k 词
前言该文章旨在复习左程云算法与数据结构基础班暴力递归算法,对应视频: https://www.bilibili.com/video/BV13g41157hK?p=11https://www.bilibili.com/video/BV13g41157hK?p=12 暴力递归暴力递归,顾名思义就是把所有的情况全部穷举一遍,然后看正确的是那些,并且保存下来,对于这种题没有固定的模板,对于不同的问题,有着不同的业务要求,有着不同的暴力策略,我们直接来一道题进入这个算法的奇妙之中。 字符串的子序列无重字符想要生成生成一个字符串的所有子序列,应该对其每个位置的字符进行选择,可选是否选择这个字符,或者不选择这个字符,你可以把选择这个过程放在一颗二叉树上,选择的节点就是新生成的字符串,而路径就是是否选择该字符,而遍历的过程其实就是生成一个这样的二叉树,我们获取答案,只需在每个节点走到树底的位置保存即可。 一起来看下代码实现把: public static void printAllSubsquences(String str) { // 先把字符串转为字符数组 ch...
4.2k 词
前言今天是打卡学习labuladong的算法笔记第2个月零8天,今天来回顾一下反转链表的各种问题,这篇文章会带你循序渐进的学会各种反转链表的“花招”,从反转整个链表,到反转链表开头n个元素,然后到反转链表一个区间里的元素,再到k个一组反转链表。 复盘不懂链表的也没有关系,我下面会介绍一些链表,根据这个名字,肯定就可以猜到这是一种像链子一样的数据结构,它同时包含了递归和迭代性质,类型名通常为ListNode,下面是java代码实现: // 单链表节点的结构 public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } 好,在了解了基本的链表结构后,我们就可以学习反转链表了(坏笑) 反转整个链表我们先来看下这道简单题,就是将整个链表反转:【leetcode 206:反转链表】 迭代的方式解决: class Solution { public ListNode reverseList(ListNode hea...
2.1k 词
前言最近看到这么一个故事,名为田忌赛马,故事是这样的: 田忌和齐王赛马,两人的马分上中下三等,如果同等级的马对应着比赛,田忌赢不了齐王。但是田忌遇到了孙膑,孙膑就教他用自己的下等马对齐王的上等马,再用自己的上等马对齐王的中等马,最后用自己的中等马对齐王的下等马,结果三局两胜,田忌赢了。 这只是三匹马对三匹马的情况,如果是一百匹呢,孙膑肯定就算不过来了,那么对于这问题,用什么算法可以解决呢? 算法分析这个算法的主要思路是: 打得过就打,打不过就用最弱的去换对面的强马 但是你也许会想:直接打得过就打的话,如果我的弱一点的马也打得过对面的马,那么战力是不是有点浪费了? 其实这样想是多此一举了,我们假设田忌的一等马为T1,二等马为T2,齐王的一等马为O1,田忌的一二等马均打得过,假设我们用T2去打对面的O1,打过了,可是你仔细一想,对面最强的已经死了,我们最强的马是为了打谁而准备的呢?所以说,这种想法根本是没必要的,就好比你考试考60分就过了,你多考几分还是没什么大用。 对于这种优势最大化问题,力扣上也有类似的,比如:【leetcode 870:优势洗牌】 给定两个长度相等的数...