P7078 [CSP-S2020] 贪吃蛇 题解

news/2024/10/6 15:15:35/文章来源:https://www.cnblogs.com/sea-and-sky/p/18449088

P7078 [CSP-S2020] 贪吃蛇

这题好啊

题目传送门

看到题之后觉得有点像砍蚯蚓的那道题

看看题目

可以证明,若一条蛇在吃完之后不是最弱的那一条蛇,那么他一定会选择吃,证明如下

设蛇长为 \(a_{1, \dots ,n}\) 且依次递增,那么很明显的

因为

​ $$a_x>a_y>a_n>a_m$$
​ $$ a_x-a_m>a_y-a_n$$
也就是说,这条蛇吃掉后面的蛇之后产生的蛇永远都不会是最小的哪一个

而如果一条蛇在吃完了之后是最弱的蛇,那么他为了保命,会看自己吃了之后会不会被吃,也就是看下一条蛇的决策

而下一条蛇的决策过程和这一条蛇也是一样的,这种情况就可以 递归的来判断.

还要补充两点

  • 如何维护最强最弱的蛇?

可以用平衡树,set 等,但这种做法会带上一只 \(log\) ,所以一般会T

正确的做法是像砍蚯蚓的那道题一样,用双端队列维护

像这道题,用两个双端队列,一个维护所有原来的蛇,另一个维护吃完蛇后产生的蛇.

对于第二个双端队列的单调性的证明,就是我们一开始证的东西, 后吃的蛇所产生的蛇的长度一定 比 先吃的产生的长度小.

  • 处理一次第二种情况后就可以立即停止了

这是因为第二种情况若吃了,就说明下一条蛇不会吃,结束

若没吃,也结束

上代码!

点击查看代码

#include <bits/stdc++.h>
using namespace std;
struct snack
{int len, num;friend bool operator<(const snack &a, const snack &b){if (a.len == b.len)return a.num < b.num;return a.len < b.len;}friend bool operator>(const snack &a, const snack &b){if (a.len == b.len)return a.num > b.num;return a.len > b.len;}friend snack operator-(const snack &a, const snack &b){snack tmp;tmp.len = a.len - b.len;tmp.num = a.num;return tmp;}void clear(){this->len = 0;this->num = 0;}
};
snack snac[10000100]; //蛇群们
int t, n, k;
deque<snack> q1, q2; //两个双端队列来维护
void clean_up()
{q1.clear();q2.clear();
}
snack get_min(bool delt)
{snack ll;if (q1.empty() && q2.empty()){snack insid;insid.len = -1;insid.num = -1;return insid;}else if (q1.empty()){ll = q2.front();if (delt)q2.pop_front();return ll;}else if (q2.empty()){ll = q1.front();if (delt)q1.pop_front();return ll;}else{if (q1.front() < q2.front()){ll = q1.front();if (delt)q1.pop_front();return ll;}else{ll = q2.front();if (delt)q2.pop_front();return ll;}}
}
snack get_max(bool del)
{snack ll;if (q1.empty() && q2.empty()){snack insid;insid.len = -1;insid.num = -1;return insid;}else if (q1.empty()){ll = q2.back();if (del)q2.pop_back();return ll;}else if (q2.empty()){ll = q1.back();if (del)q1.pop_back();return ll;}else{if (q1.back() > q2.back()){ll = q1.back();if (del)q1.pop_back();return ll;}else{ll = q2.back();if (del)q2.pop_back();return ll;}}
}
int lef = n, llef;
bool fight()
{snack min_, max_;if (llef == 2){return 1;}min_ = get_min(1);max_ = get_max(1);if (max_ - min_ > get_min(0)){return 1;}else{llef--;q2.push_front(max_-min_);return !fight();}
}
int solve()
{for (int ww = 1; ww <= n; ww++){q1.push_back(snac[ww]);}// case1;lef = n;snack new_, tmp;while (1){if (lef == 2){lef--;}if (lef == 1){break;}new_ = get_min(1);tmp = get_max(1);// cout<<"get "<<new_.len<<" "<<tmp.len<<endl;//   cout<<(tmp-new_).len<<" 对 " <<get_min(0).len<<endl;if (tmp - new_ > get_min(0)){q2.push_front(tmp - new_);lef--;}else{q2.push_front(tmp - new_);break;}}if (lef == 1){return lef;}// case2,判断完直接就结束了llef = lef;if (!fight()){lef--;}return lef;
}
int main()
{freopen("P7078_5.in","r",stdin);ios::sync_with_stdio(false);cin >> t;cin >> n;for (int yy = 1; yy <= n; yy++){cin >> snac[yy].len;snac[yy].num = yy;}cout << solve() << "\n";for (int ww = 2; ww <= t; ww++){clean_up();cin >> k;int a, b;for (int ww = 1; ww <= k; ww++){cin >> a >> b;snac[a].len = b;}cout << solve() << "\n";}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809055.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

睡岗识别 AI助力企业安全管控

睡岗识别可以通过AI视频智能分析技术,睡岗识别识别出操作人员是否存在睡岗情况。例如,在变电站等场景中,睡岗识别技术可以通过对识别出操作人员是否存在睡岗情况,及时发出预警,避免因操作人员的疏忽而导致的安全事故。在工厂车间中,睡岗识别技术可以通过对工人的行为进行…

加油站安全风险监测预警系统

加油站安全风险监测预警系统可以通过对加油站设备、环境、人员等方面进行监测,加油站安全风险监测预警系统实现对加油站的全面监管。例如,在加油站油罐区中,加油站安全风险监测预警系统可以对加油站人员抽烟打电话、明火烟雾等环境安全隐患进行自动识别,及时发出预警,避免…

山西煤矿电子封条

山西煤矿电子封条通过AI视觉分析技术,山西煤矿电子封条实现对各矿区(煤矿和非煤矿区)每日矿井出入井人监察控制、调度室空岗识别、煤矿生产作业状态、摄像头遮挡、挪动角度识别、货运车辆出矿识别等。山西煤矿电子封条实现当前待办事项的推送,以及对各矿区用户区域内的报警…

离岗识别 AI助力企业安全管控

离岗识别通过yolov5网络模型技术,离岗识别可以自动识别办公室、工厂、监控室监控画面中人员离岗脱岗睡岗等行为,发现违规行为立即抓拍告警并同步睡岗离岗等违规数据到后台提醒值班人员及时处理。离岗识别采用人工智能算法识别技术对各主控室、办公室、工厂、煤矿监控室等人员…

登高作业安全带穿戴识别系统 - 保障登高作业人员安全

登高作业安全带穿戴识别系统是一种通过Ai视觉智能分析技术,登高作业安全带穿戴识别系统实现对登高作业人员是否穿戴安全带进行监测的系统,登高作业安全带穿戴识别系统通过视频监控智能识别技术检测登高作业人员是否佩戴安全带,并及时发出警报,以提醒工作人员及时穿戴安全带…

MySQL单表存多大的数据量比较合适

前言 经常使用MySQL数据库的小伙伴都知道,当单表数据量达到一定的规模以后,查询性能就会显著降低。因此,当单表数据量过大时,我们往往要考虑进行分库分表。那么如何计算单表存储多大的数据量合适?当单表数据达到多大的规模时,我们才要进行分库分表呢? MySQL存储方式 首先…

【THM】kiba练习

脚本小子是这样的,黑客只要写POC就可以,可是脚本小子要考虑的事情就多了。 学到了新知识:利用网上的POC进行复现、利用Capabilities进行提权【THM】kiba练习 与本文相关的TryHackMe实验房间链接:TryHackMe | kiba 简介:识别数据可视化仪表板中允许执行远程代码执行的关键…

信息学奥赛复赛复习13-CSP-J2021-02插入排序-排序稳定性、插入排序、sort排序、结构体、计数排序

PDF文档公众号回复关键字:202410061P7910 [CSP-J 2021] 插入排序 [题目描述] 插入排序是一种非常常见且简单的排序算法。小 Z 是一名大一的新生,今天 H 老师刚刚在上课的时候讲了插入排序算法。 假设比较两个元素的时间为 O(1),则插入排序可以以 O(n^2) 的时间复杂度完成长度…

信息学奥赛复赛复习13-CSP-J2021-02插入排序-排序稳定性、插入排序、sort排序、结构图、计数排序

PDF文档公众号回复关键字:202410061P7910 [CSP-J 2021] 插入排序 [题目描述] 插入排序是一种非常常见且简单的排序算法。小 Z 是一名大一的新生,今天 H 老师刚刚在上课的时候讲了插入排序算法。 假设比较两个元素的时间为 O(1),则插入排序可以以 O(n^2) 的时间复杂度完成长度…

vue3 watch方法---监视基本类型数据

watch 监听定义的数据发生改变的时候执行什么函数 watch 方法有两个参数 watch(sum,箭头函数) 这个箭头函数里面有两个参数(newValue,oldValue)=> {},如下代码<template><!-- watch;监视数据变化 vue3 可以监视一下四种数据类型:ref定义的数据reactive 定义的…

2024-2025-1 20241421 《计算机基础与程序设计》第二周学习总结

这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK02这个作业的目标 数字化、信息安全、自学教材计算机科学概论(第七版)第1章并完成云班课测试、 《C语言程序设计》第1章并完成云班课测试作业正…

学期(2024-2025-1) 学号20241425 《计算机基础与程序设计》第2周学习总结

学期(2024-2025-1) 学号20241425 《计算机基础与程序设计》第2周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>([2024-2025-1计算机基础与程序设计第二周作业]https://www.cnblo…