AcWing1088.旅行问题

博客详细探讨了AcWing在线编程平台上的第1088题——旅行问题。文章通过分析题目,引导读者理解问题本质,并重点讲解如何运用动态规划和队列数据结构来解决这一问题。在代码实现部分,虽然存在一些小问题,但整体思路清晰,有助于读者提升算法应用能力。

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

link

代码好像还有一点问题

/*
数组没开够,爆零两行泪
longlong开成int,爆零两行泪
多组忘清空,爆零两行泪
 dp 没初值,爆零两行泪
深搜没边界,爆零两行泪
广搜忘出队,爆零两行泪
输入没加 &,爆零两行泪
模数没看见,爆零两行泪
 -1 不输出,爆零两行泪
越界不特判,爆零两行泪
线段树开一倍,爆零两行泪
无向变有向,爆零两行泪
题意没审清,爆零两行泪
文件名起错,爆零两行泪
调试忘删除,爆零两行泪
没用freopen,爆零两行泪
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+16;//破幻成殓,卡二倍空间 
int n;
int o[N],d[N],q[N];//q[hh]是最小区间和的下标 
ll s[N];
bool ans[N];//标记数组 
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>o[i]>>d[i];
	}
	for(int i=1;i<=n;i++){
		s[i]=s[i+n]=o[i]-d[i];//把油量和距离一起处理; 
	}
	//顺时针处理 ,也就是从1~n 
	int hh=0,tt=-1;
	for(int i=1;i<=n*2;i++) s[i]+=s[i-1];
	for(int i=n*2;i>=1;i--){
		if(hh<=tt&&q[hh]>=i+n) hh++;//数超范围 
		while(hh<=tt&&s[q[tt]>=s[i]]) tt--;//最小值先更新再求 
		q[++tt]=i;
		if(i<=n){
			if(s[q[hh]]>=s[i-1]) ans[i]=true;
		}
	}
// 	逆时针数
	hh=0,tt=-1;
	d[0]=d[n];
	for(int i=1;i<=n;i++) s[i]=s[i+n]=o[i]-d[i-1];
	for(int i=1;i<=n*2;i++) s[i]+=s[i-1];
	for(int i=1;i<=n*2;i++){
		if(hh<=tt&&q[hh]<i-n) hh++;//超出范围,必须在i-1到i-n 
		if(i>n){
			if(s[q[hh]]<=s[i]) ans[i-n]=true;//即s[i]-s[q[hh]]>=0油还有剩余,能到i 
		}
		while(hh<=tt&&s[q[tt]]<=s[i]) tt--;//最小值先求再更新 
		q[++tt]=i;
	}
	for(int i=1;i<=n;i++){
		if(ans[i]) puts("TAK");
		else puts("NIE");
	}
	return 0;
}
/*
考虑处理环行;
可以枚举从i点出发,再到达i点   i∈[1,n]; 
大概是这样 
/----------------->|
  /----------------->|
    /----------------->|
	(省略) 
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
对于从1开始又等价于s[i]>=0, i∈[1,n],s[]是前缀和数组;
也就是中途油箱中油量不能为负 
也就是对于每个点,找区间最小值,若最小值>=0,则安全 
按照惯例,预处理前缀和
正反两个方向扫描 
对于区间i,j,每个s[i]大小是固定的,所以要求s[j]的最小值 
*/
### 如何用 Python 实现单链表 #### 定义节点类 为了构建单链表,首先定义一个 `Node` 类来表示链表中的每个节点。每个节点包含两个属性:数据 (`data`) 和指向下一个节点的指针 (`next`)。 ```python class Node: def __init__(self, data=None): self.data = data # 节点存储的数据 self.next = None # 指向下一个节点的指针 ``` #### 定义链表类 接着定义一个 `LinkedList` 类用于管理这些节点,并提供一些基本操作方法: ```python class LinkedList: def __init__(self): self.head = None # 初始化头结点为空 def append(self, data): new_node = Node(data) if not self.head: # 如果当前列表为空,则设置新加入的元素为首元节点 self.head = new_node return last = self.head while last.next: # 找到链表最后一个位置 last = last.next last.next = new_node # 将新的节点连接到最后面 def display(self): elements = [] current_node = self.head while current_node: elements.append(current_node.data) current_node = current_node.next print(elements) def insert_at_beginning(self, data): new_node = Node(data) new_node.next = self.head self.head = new_node def delete_by_value(self, key): cur_node = self.head if cur_node and cur_node.data == key: self.head = cur_node.next cur_node = None return prev = None while cur_node and cur_node.data != key: prev = cur_node cur_node = cur_node.next if cur_node is None: return prev.next = cur_node.next cur_node = None ``` 此部分代码实现了创建一个新的节点并将其添加至链表末端的功能[^1]。此外还提供了打印整个链表以及删除指定值的方法。 对于AcWing 826题目而言,上述基础功能已经足够解决该问题的需求。如果需要更复杂的操作比如反转链表、查找倒数第K个节点等功能可以根据具体需求进一步扩展此类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值