puzzle(1241)称重问题

本文探讨了在没有砝码和有限次称重条件下,如何识别出不同重量硬币的问题。针对12个和13个球的情况,详细阐述了如何在3次称重中找到不同重量的球。同时,介绍了最大-最小称重问题,旨在找出最轻和最重的硬币。此外,还涉及到了有砝码称重问题,通过一次称重策略确定全部假币的一堆。

目录

一,无砝码称重问题

1,算法谜题 44 孰轻孰重

2,12个球称重

3,13个球称重

4,算法谜题 95 最大-最小称重

二,有砝码称重问题

1,算法谜题 11 假币堆问题


一,无砝码称重问题

1,算法谜题 44 孰轻孰重

有 n>2 个外观完全相同的硬币和一个没有砝码可用的双托盘天平。硬币中有一枚假币, 但不知道假币是比真币轻还是重, 其余的真币的重量都一样。设计一个算法, 用最少的称重次数判断假币真币孰轻孰重。

2,12个球称重

有12个球,其中一个质量不同,但不知道是更轻还是更重。请用天平称3次,把那个球找出来,并判断其是偏重还是偏轻。

答案:

第一次称必定是左边4个球,右边4个球,否则的话,如果至少有5个球,那么在2边不平衡的情况下就至少有10种情况,2次是无法分辨的,如果最多有3个球,那么在2边平衡的情况下就至少有12种情况,2次是无法分辨的。

左边4个球,右边4个球,无论是平衡还是不平衡,都有8种情况,所以2次都是有可能够的。

假设左边的4个球是1,2,3,4,右边的4个球是5,6,7,8,剩下的4个球是9,10,11,12

如果平衡的话,那么8个球都是正常的球,第2次称的时候左边放1,2,3,右边放9,10,11,后面自然就知道该怎么办了。第2次称还有1种方法,左边放1,9,右边放10,11,只有这2种方法了,理由和上面说的差不多。

如果不平衡的话,不妨设左边的4个球较重,第2次称有很多方法,例如,左边放1,2,5,右边放3,4,6,又例如,左边放1,2,3,5,右边放4,9,10,11,又例如,左边放1,2,3,5,6,右边放4,9,10,11,12,等等。后面自然就知道该怎么办了。

3,13个球称重

有13个球,其中一个质量不同,但不知道是更轻还是更重。请用天平称3次,把那个球找出来。

注:如果仅仅把上一题的12改成13的话,一定是无解的。所以本题是只需要找出球,不需要判断是偏轻还是偏重。

答案:

首先,我们依然可以得到结论,第1次称必定只能是左边4个球,右边4个球。理由和上题中的类似,稍微复杂一点。

假设左边的4个球是1,2,3,4,右边的4个球是5,6,7,8,剩下的5个球是9,10,11,12,13

如果平衡的话,第2次称可以左边放1,2,3,右边放9,10,11,后面自然就知道该怎么办了。

如果不平衡的话,那么就可以直接用上题的方法完成了。
 

4,算法谜题 95 最大-最小称重

给定 n>1 个硬币以及一个没有秤砣的天平秤, 请你在 (3n - 3) / 2 次称重中, 找出最轻的硬币和最重的硬币。

二,有砝码称重问题

1,算法谜题 11 假币堆问题

有 10 堆 10 枚外观完全一致的硬币, 其中有一堆全部都是假币, 其他各堆中的硬币都是真币。所有的真币重量都是 10 克, 假币则重 11 克。你有一把示数可读的秤, 可以称出任意数目硬币的实际重量。问最少称几次才能将全部都是假币的那堆硬币辨别出来?

只需要一次。将硬币堆从 1 到 10 进行标记。从第一堆硬币中取出一枚硬币, 从第二堆中取出两枚, 以此类推, 直到从最后一堆硬币中取出 10 枚硬币。称出所有这些取出来的硬币的总重量。与 550 做差, 差值就指示着假币堆的标号。例如, 如果取出硬币的重量是 553 克, 则 3 枚硬币是假币, 因此是第三个硬币堆是假币。

### 使用回溯算法求解8-Puzzle问题 #### 方法概述 八数码谜题(8-puzzle),也称为九宫格拼图,是一个典型的组合搜索问题。该问题的目标是从初始状态到达目标状态,其中只有一个空白位置允许相邻的瓷砖移动。为了利用回溯法解决此问题,需要定义一个递归函数来探索所有可能的状态转换路径直到找到解决方案。 在每次迭代过程中,程序会尝试将当前空位与其四个方向上的任意一块合法邻近砖块交换位置,并记录下新的棋盘布局作为下一步操作的基础。如果某一步骤达到了预期的结果,则返回成功;否则继续深入未访问过的节点进行试探直至穷尽一切可能性或发现解答为止[^1]。 #### 实现细节 以下是Python实现的一个简单版本: ```python from copy import deepcopy def is_goal(state, goal_state): """判断是否达到目标""" return state == goal_state def find_blank_position(puzzle): """查找空白的位置""" for i in range(len(puzzle)): try: j = puzzle[i].index(0) return (i,j) except ValueError: continue raise Exception('No blank position found') moves = [(0,-1), (-1,0), (0,+1), (+1,0)] # 左 上 右 下 移动向量 def move_tile(puzzle, direction): """按照指定的方向移动空白处旁边的瓦片""" new_puzzle = deepcopy(puzzle) row,col=find_blank_position(new_puzzle) drow,dcol=direction target_row,target_col=row+drow,col+dcol if not ((0<=target_row<len(new_puzzle)) and (0<=target_col<len(new_puzzle))): return None temp=new_puzzle[target_row][target_col] new_puzzle[row][col]=temp new_puzzle[target_row][target_col]=0 return new_puzzle def backtrack_search(initial_state, goal_state): def _backtrack(current_path): current_board=current_path[-1] if is_goal(current_board,goal_state): print("Solution Found!") for step in current_path: display(step) return True possible_moves=[move for move in moves \ if move_tile(current_board,move)] visited_states=set([str(x)for x in current_path]) unvisited_neighbors=[state for state in possible_moves\ if str(state)not in visited_states] for neighbor in unvisited_neighbors: next_path=current_path+[neighbor] result=_backtrack(next_path) if result==True:return True return False start=[[initial_state]] solution_found=_backtrack(start) if not solution_found: print("No Solution Exists.") ``` 这段代码展示了如何使用回溯方法寻找从给定起始配置到结束配置的有效序列。注意这里简化了一些实际应用中的考虑因素,比如剪枝策略和启发式评估等,这些都可以进一步提高效率[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值