I - Large Division

本文介绍了一种高效判断大整数a是否能被较小整数b整除的方法。通过将大整数逐位处理并利用模运算,避免了直接进行大整数运算可能带来的复杂度和溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I - Large Division


Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if there exists an integer c such that a = b * c.

Input

Input starts with an integer T (≤ 525), denoting the number of test cases.

Each case starts with a line containing two integers a (-10200 ≤ a ≤ 10200) and b (|b| > 0, b fits into a 32 bit signed integer). Numbers will not contain leading zeroes.

Output

For each case, print the case number first. Then print 'divisible' if a is divisible by b. Otherwise print 'not divisible'.

Sample Input

6

101 101

0 67

-101 101

7678123668327637674887634 101

11010000000000000000 256

-202202202202000202202202 -101

Sample Output

Case 1: divisible

Case 2: divisible

Case 3: divisible

Case 4: not divisible

Case 5: divisible

Case 6: divisible


题意:给你一个超大的a,和一个不太大的b,让你判断a是否能被b整除;

主要是一个公式吧。

res=(res*10+s[ i])%b;

听说是同余得到的;

其实仔细想一下就知道,这个就是把一个大整数拆分成很多部分,对每个部分求余。


代码:


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;


typedef long long ll;
int main()
{
    int T;
    scanf("%d",&T);
    ll b;
    char s[1001];
    int kase=1;
    while(T--)
    {
        scanf("%s%lld",s,&b);
        if(b<0)
            b=-b;
        ll res=0;
        for(int i=0;i<strlen(s);i++)
        {
            if(s[i]=='-') continue;
            res=res*10+s[i]-'0';
            res=res%b;
        }
        res=res%b;
        printf("Case %d: ",kase++);
        if(res)
            printf("not divisible\n");
        else
            printf("divisible\n");
    }
    return 0;
}










lass RRTStar3D: def __init__(self, start, goal, builds, bounds, max_iter=RRT_MAX_ITER, step_size=RRT_STEP, neighbor_radius=RRT_NEIGHBOR_RADIUS): self.start = np.array(start) self.goal = np.array(goal) # Pre-calculate builds with safety height buffer self.builds_with_safety = builds.copy() self.builds_with_safety[:, 4] -= SAFE_HEIGHT # Decrease zmin self.builds_with_safety[:, 5] += SAFE_HEIGHT # Increase zmax # Ensure zmin is not negative if SAFE_HEIGHT is large self.builds_with_safety[:, 4] = np.maximum(0, self.builds_with_safety[:, 4]) self.bounds = np.array(bounds) # Ensure bounds is numpy array self.max_iter = max_iter self.step_size = step_size self.neighbor_radius = neighbor_radius self.nodes = [self.start] self.parent = {tuple(self.start): None} self.cost = {tuple(self.start): 0.0} # Initialize KDTree with the start node self.kdtree = cKDTree(np.array([self.start])) # Ensure it's a 2D array def sample(self): # Biased sampling towards goal occasionally if np.random.rand() < 0.1: # 10% chance to sample goal return self.goal # Sample within bounds return np.random.uniform(self.bounds[:, 0], self.bounds[:, 1]) def nearest(self, q): _, idx = self.kdtree.query(q) # Handle case where KDTree might have only one node initially if isinstance(idx, (int, np.integer)): return self.nodes[idx] else: # Should not happen if tree has >= 1 node, but safety check return self.nodes[0] def steer(self, q_near, q_rand): delta = q_rand - q_near dist = np.linalg.norm(delta) if dist == 0: # Avoid division by zero return q_near ratio = self.step_size / dist if ratio >= 1.0: return q_rand return q_near + delta * ratio def near_neighbors(self, q_new): # Ensure nodes list is not empty before querying if not self.nodes: return [] # Ensure kdtree has points before querying if self.kdtree.n == 0: return [] # Use query_ball_point which is efficient for radius searches indices = self.kdtree.query_ball_point(q_new, self.neighbor_radius) # Filter out the index of q_new itself if it's already in nodes (might happen during rewiring) q_new_tuple = tuple(q_new) neighbors = [] for i in indices: # Check bounds and ensure it's not the node itself if already added # This check might be redundant if q_new isn't added before calling this if i < len(self.nodes): # Ensure index is valid node = self.nodes[i] if tuple(node) != q_new_tuple: neighbors.append(node) return neighbors def plan(self): for i in range(self.max_iter): q_rand = self.sample() # Check if nodes list is empty (shouldn't happen after init) if not self.nodes: print("Warning: Node list empty during planning.") continue # Or handle appropriately q_near = self.nearest(q_rand) q_new = self.steer(q_near, q_rand) # Check collision for the new segment using the pre-calculated safe builds if check_segment_collision(q_near, q_new, self.builds_with_safety) > 0: continue # If collision-free, add the node and update KD-Tree periodically q_new_tuple = tuple(q_new) q_near_tuple = tuple(q_near) # Choose parent with minimum cost among neighbors min_cost = self.cost[q_near_tuple] + np.linalg.norm(q_new - q_near) best_parent_node = q_near neighbors = self.near_neighbors(q_new) # Find neighbors first for q_neighbor in neighbors: q_neighbor_tuple = tuple(q_neighbor) # Check connectivity collision if check_segment_collision(q_neighbor, q_new, self.builds_with_safety) == 0: new_cost = self.cost[q_neighbor_tuple] + np.linalg.norm(q_new - q_neighbor) if new_cost < min_cost: min_cost = new_cost best_parent_node = q_neighbor # Add the new node with the best parent found self.nodes.append(q_new) q_best_parent_tuple = tuple(best_parent_node) self.parent[q_new_tuple] = q_best_parent_tuple self.cost[q_new_tuple] = min_cost # Rebuild KDTree periodically if len(self.nodes) % KD_REBUILD_EVERY == 0 or i == self.max_iter - 1: # Important: Ensure nodes is a list of arrays before creating KDTree if self.nodes: # Check if nodes is not empty self.kdtree = cKDTree(np.array(self.nodes)) # Rewire neighbors to go through q_new if it provides a shorter path for q_neighbor in neighbors: q_neighbor_tuple = tuple(q_neighbor) # Check if rewiring through q_new is shorter and collision-free cost_via_new = min_cost + np.linalg.norm(q_neighbor - q_new) if cost_via_new < self.cost[q_neighbor_tuple]: if check_segment_collision(q_new, q_neighbor, self.builds_with_safety) == 0: self.parent[q_neighbor_tuple] = q_new_tuple self.cost[q_neighbor_tuple] = cost_via_new # Check if goal is reached if np.linalg.norm(q_new - self.goal) < self.step_size: # Check final segment collision if check_segment_collision(q_new, self.goal, self.builds_with_safety) == 0: goal_tuple = tuple(self.goal) self.nodes.append(self.goal) # Add goal node self.parent[goal_tuple] = q_new_tuple self.cost[goal_tuple] = min_cost + np.linalg.norm(self.goal - q_new) print(f"RRT*: Goal reached at iteration {i+1}") # Rebuild KDTree one last time if goal is reached self.kdtree = cKDTree(np.array(self.nodes)) break # Exit planning loop else: # Loop finished without reaching goal condition print(f"RRT*: Max iterations ({self.max_iter}) reached. Connecting nearest node to goal.") # Find node closest to goal among existing nodes if not self.nodes: print("Error: No nodes generated by RRT*.") return None # Or raise error nodes_arr = np.array(self.nodes) distances_to_goal = np.linalg.norm(nodes_arr - self.goal, axis=1) nearest_node_idx = np.argmin(distances_to_goal) q_final_near = self.nodes[nearest_node_idx] q_final_near_tuple = tuple(q_final_near) goal_tuple = tuple(self.goal) # Try connecting nearest found node to goal if check_segment_collision(q_final_near, self.goal, self.builds_with_safety) == 0: self.nodes.append(self.goal) self.parent[goal_tuple] = q_final_near_tuple self.cost[goal_tuple] = self.cost[q_final_near_tuple] + np.linalg.norm(self.goal - q_final_near) print("RRT*: Connected nearest node to goal.") else: print("RRT*: Could not connect nearest node to goal collision-free. Returning path to nearest node.") # Path will be constructed to q_final_near instead of goal goal_tuple = q_final_near_tuple # Target for path reconstruction # Backtrack path from goal (or nearest reachable node) path = [] # Start backtracking from the actual last node added (goal or nearest) curr_tuple = goal_tuple if curr_tuple not in self.parent and curr_tuple != tuple(self.start): print(f"Warning: Target node {curr_tuple} not found in parent dict. Path reconstruction might fail.") # Fallback to the last added node if goal wasn't reachable/added correctly if self.nodes: curr_tuple = tuple(self.nodes[-1]) else: return None # No path possible while curr_tuple is not None: # Ensure the node corresponding to the tuple exists # This requires searching self.nodes, which is inefficient. # A better approach is to store nodes in the dict or use indices. # For now, let's assume tuple keys match numpy arrays. path.append(np.array(curr_tuple)) curr_tuple = self.parent.get(curr_tuple, None) if not path: print("Error: Path reconstruction failed.") return None if tuple(path[-1]) != tuple(self.start): print("Warning: Path does not end at start node.") return np.array(path[::-1]) # Reverse to get start -> goal order # --------------------- Path Cost Function (Use safe builds) --------------------- def path_cost(path_pts, builds_with_safety, drone_speed=DRONE_SPEED, penalty_k=PENALTY_K): total_time = 0.0 total_penalty = 0.0 num_segments = len(path_pts) - 1 if num_segments < 1: return 0.0 # No cost for a single point path # Vectorized calculations where possible p = path_pts[:-1] # Start points of segments q = path_pts[1:] # End points of segments segments = q - p distances = np.linalg.norm(segments, axis=1) # Avoid division by zero for zero-length segments valid_segments = distances > 1e-6 if not np.any(valid_segments): return 0.0 # Path has no length p = p[valid_segments] q = q[valid_segments] segments = segments[valid_segments] distances = distances[valid_segments] dir_unit = segments / distances[:, np.newaxis] # Interpolate wind at midpoints for better average (optional, could use start/end) midpoints = p + segments / 2.0 # try: # wind_vectors = interp(midpoints) # except ValueError as e: # print(f"Interpolation error: {e}") # print(f"Midpoints shape: {midpoints.shape}") # # Handle error, e.g., return a large cost or use zero wind # wind_vectors = np.zeros_like(midpoints) # Calculate ground speed component along each segment # Ensure wind_vectors and dir_unit have compatible shapes for dot product # np.einsum is efficient for row-wise dot products # wind_along_path = np.einsum('ij,ij->i', wind_vectors, dir_unit) ground_speeds = np.maximum(drone_speed , 1e-3) # Avoid zero/negative speed # Calculate time for each segment segment_times = distances / ground_speeds total_time = np.sum(segment_times) # Calculate collision penalty (iterate segments as check_segment_collision is per-segment) for i in range(len(p)): # Pass pre-calculated builds_with_safety penetration = check_segment_collision(p[i], q[i], builds_with_safety) if penetration > 0: total_penalty += penalty_k * penetration**2 # Quadratic penalty return total_time + total_penalty生成注释
最新发布
05-14
<think>好的,我现在需要帮用户为RRTStar3D类和path_cost函数生成详细的注释。用户之前已经讨论过RRT*的原理,现在转向具体的代码实现。用户提供的引用内容涉及A*算法、停车路径规划、碰撞检测、交通规则处理等,但看起来这些引用可能和当前问题关联不大,不过用户特别提到要参考上一次的问题和回答,也就是关于RRT*的原理部分。 首先,我需要确定用户的需求。用户想为RRTStar3D类和path_cost函数添加详细注释,解释每个方法的作用、参数意义以及算法的核心逻辑。用户可能正在学习路径规划算法,或者在实际项目中需要理解和修改RRT*的代码,因此需要清晰的文档来辅助理解。 接下来,我需要回忆RRT*算法的关键点,尤其是三维空间中的实现。RRT*在RRT基础上增加了重布线和父节点优化,以实现渐进最优。在三维空间中,需要考虑三维坐标、碰撞检测在3D环境中的处理,以及距离计算可能使用欧氏距离或其他度量。 用户提供的引用中提到了A*算法的参数,比如障碍物坐标列表、分辨率、机器人半径等,这些可能在RRT*的3D实现中也有类似参数,比如三维障碍物地图、步长、搜索半径等。此外,碰撞检测模块在引用2中也有涉及,可能需要考虑如何将二维的障碍物检测扩展到三维。 接下来,我需要考虑如何结构化注释。通常,类注释应包括类的整体职责、核心方法、属性。每个方法需要说明功能、参数、返回值,可能还要提到算法步骤。path_cost函数可能需要解释其计算路径成本的逻辑,是否考虑欧氏距离或其他因素。 需要注意的是,用户可能希望注释不仅描述代码做了什么,还要解释为什么这么做,即与RRT*算法原理的联系。例如,在父节点优化步骤中,搜索邻近节点并选择成本最低的路径,这在注释中应关联到渐进最优性。 可能还需要考虑代码中的特定实现细节,比如三维空间的节点表示(可能用(x, y, z))、碰撞检测的实现方式(是否使用体素网格或其他方法)、重布线时的半径计算等。此外,path_cost函数可能累计从起点到当前节点的路径长度,每次添加新节点时更新成本。 用户可能存在的深层需求是理解代码如何将RRT*的理论应用到三维环境中,如何处理三维空间中的碰撞检测,以及如何优化路径成本。因此,在注释中需要明确这些方面,特别是在参数和算法步骤中体现三维特性。 最后,确保注释符合Python的文档规范,比如使用docstring,参数和返回值说明清晰,变量名有解释,并引用相关算法的步骤,如重布线和父节点优化。同时,可能需要提醒用户注意代码中的关键部分,如碰撞检测的实现可能影响性能,或者搜索半径的选择对算法效率的影响。</think>以下是为`RRTStar3D`类和`path_cost`函数设计的详细注释,结合RRT*算法原理与三维路径规划实现: --- ### RRTStar3D类注释 ```python class RRTStar3D: """ 三维空间中基于RRT*算法的路径规划器,支持渐进最优路径搜索 核心功能:三维空间采样、碰撞检测、父节点优化、重布线 """ def __init__(self, start, goal, obstacle_list, rand_area, expand_dis=3.0, path_resolution=0.5, max_iter=500): """ 初始化三维RRT*规划器 参数: start : tuple # 起点坐标(x, y, z) goal : tuple # 目标点坐标(x, y, z) obstacle_list : list # 障碍物列表,每个元素为包含位置和半径的字典: # [{'pos': (x,y,z), 'radius': r}, ...] rand_area : list # 三维采样区域[[x_min, x_max], [y_min, y_max], [z_min, z_max]] expand_dis : float # 单步扩展最大距离(控制树生长速度) path_resolution : float # 路径离散化精度(用于碰撞检测) max_iter : int # 最大迭代次数 """ # 存储障碍物信息用于碰撞检测[^2] self.obstacle_list = obstacle_list # 节点集合,每个节点存储坐标、父节点索引、累积路径成本 self.node_list = [{'pos': start, 'parent': -1, 'cost': 0.0}] self.goal = goal # 其他参数初始化... def plan(self): """ 主路径规划函数,包含RRT*核心逻辑: 1. 随机采样与最近邻搜索 2. 新节点生成与碰撞检测[^2] 3. 父节点优化(选择最小成本路径) 4. 重布线(优化局部路径) """ # 算法主循环... def _steer(self, from_node, to_point): """ 生成从父节点到目标点的可行路径段(考虑expand_dis限制) 参数: from_node : dict # 起始节点(包含pos/cost/parent信息) to_point : tuple # 目标点坐标(x, y, z) 返回: new_point : tuple # 实际生成的新节点坐标 """ # 计算方向向量并截断至最大扩展距离 direction = np.array(to_point) - np.array(from_node['pos']) distance = np.linalg.norm(direction) if distance > self.expand_dis: direction = direction * self.expand_dis / distance new_point = tuple(np.array(from_node['pos']) + direction) return new_point def _find_near_nodes(self, new_node): """ 寻找新节点周围可优化的邻近节点(重布线阶段使用) 参数: new_node : dict # 新生成的节点 返回: near_indices : list # 邻近节点的索引列表 """ # 计算搜索半径:r = γ*(log(n)/n)^(1/d), d=3为维度[^4] n = len(self.node_list) r = self.gamma * (np.log(n)/n) ** (1/3) # 查找所有欧氏距离小于r的节点 distances = [np.linalg.norm(np.array(node['pos']) - np.array(new_node['pos'])) for node in self.node_list] near_indices = [i for i, d in enumerate(distances) if d <= r] return near_indices def _collision_check(self, start_pos, end_pos): """ 三维线段碰撞检测(基于路径离散化) 参数: start_pos : tuple # 线段起点(x1,y1,z1) end_pos : tuple # 线段终点(x2,y2,z2) 返回: bool # True表示路径安全,False表示碰撞 """ # 将路径离散为多个检测点 points = self._discretize_path(start_pos, end_pos) # 检查每个点是否在障碍物影响范围内[^2] for p in points: for obstacle in self.obstacle_list: if np.linalg.norm(np.array(p) - np.array(obstacle['pos'])) <= obstacle['radius']: return False return True def _choose_parent(self, near_indices, new_node): """ 父节点优化:从邻近节点中选择到新节点的最小成本路径 参数: near_indices : list # 候选父节点索引列表 new_node : dict # 待优化节点 返回: min_cost : float # 最小路径成本 best_parent : int # 最优父节点索引 """ # 遍历所有候选父节点计算路径成本[^4] costs = [] for i in near_indices: parent_node = self.node_list[i] if self._collision_check(parent_node['pos'], new_node['pos']): cost = parent_node['cost'] + path_cost(parent_node['pos'], new_node['pos']) costs.append(cost) else: costs.append(float('inf')) # 选择最小成本路径... ``` --- ### path_cost函数注释 ```python def path_cost(from_point, to_point, cost_type='euclidean'): """ 计算两点间的路径成本(支持多种成本计算方式) 参数: from_point : tuple # 起点坐标(x1,y1,z1) to_point : tuple # 终点坐标(x2,y2,z2) cost_type : str # 成本计算类型 ('euclidean'/'manhattan') 返回: cost : float # 路径成本值 """ if cost_type == 'euclidean': return np.linalg.norm(np.array(to_point) - np.array(from_point)) elif cost_type == 'manhattan': return sum(abs(np.array(to_point) - np.array(from_point))) else: raise ValueError("Unsupported cost type") ``` --- ### 关键逻辑说明表 | 方法/函数 | 核心功能 | 算法关联 | |-------------------|------------------------------------------------------------------------|----------------------------| | `_steer` | 生成符合扩展距离约束的新节点坐标 | RRT基础生长逻辑[^4] | | `_find_near_nodes`| 动态计算搜索半径并寻找优化候选节点 | 渐进最优性保证的关键步骤[^4] | | `_choose_parent` | 实现父节点优化,确保新节点以最小成本接入树结构 | 路径成本优化核心[^4] | | `_collision_check`| 三维路径离散化检测,兼容球形障碍物模型 | 安全约束保障[^2] | | `path_cost` | 提供可扩展的成本计算方式,支持不同应用场景的代价函数 | 路径质量评估基础[^4] | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值