首页 > 其他分享 >2024 0713 zstu 月赛M - Packmen

2024 0713 zstu 月赛M - Packmen

时间:2024-07-16 11:53:01浏览次数:14  
标签:吃掉 位置 星号 单元格 2024 时间 zstu 游戏场地 Packmen

游戏场地是一条由1 × n个方格单元组成的带状区域。一些单元格中有吃豆人,一些单元格中有星号,其他单元格为空。

吃豆人可以在1时间单位内移动到相邻的单元格。如果目标单元格中有星号,吃豆人会吃掉它。吃豆人吃星号不需要花费任何时间。

在初始时刻,所有吃豆人开始移动。每个吃豆人可以无限次改变移动方向,但不允许超出游戏场地的边界。吃豆人的移动不会干扰其他吃豆人的移动;在一个单元格中可以有任意数量的吃豆人以任意方向移动。

你的任务是确定吃豆人吃掉所有星号的最短可能时间。

输入
第一行包含一个整数n (2 ≤ n ≤ 105) — 游戏场地的长度。

第二行包含游戏场地的描述,由n个符号组成。如果在位置i中有符号'.' — 单元格i为空。如果在位置i中有符号'*' — 单元格i中包含星号。如果在位置i中有符号'P' — 吃豆人在单元格i中。

保证游戏场地上至少有一个吃豆人和至少一个星号。

输出
打印出吃豆人吃掉所有星号的最短可能时间。

注意
在第一个示例中,位置4的吃豆人将向左移动,并吃掉位置1的星号。他将花费3时间单位。在同样的3时间单位内,位置6的吃豆人将吃掉它相邻的两个星号。例如,它可以向左移动并吃掉位置5的星号(在1时间单位内),然后从位置5向右移动并吃掉位置7的星号(在2时间单位内)。因此,在3时间单位内,吃豆人将吃掉游戏场地上的所有星号。

在第二个示例中,位置4的吃豆人将向左移动,并在2时间单位后吃掉位置3和2的星号。位置5和8的吃豆人将向右移动,并在2时间单位内分别吃掉位置7和10的星号。因此,2时间单位足够吃豆人吃掉游戏场地上的所有星号。

分析:
首先题目让我们求的是最短的可能时间,那我们可以比较容易的联想到二分时间,再去验证该时间内吃豆人能不能把所有的豆都吃掉。
先给出一个样例:
*..P.P

我们贪心的考虑,最左侧的这个*肯定是由最左侧的P吃掉,不可能由右侧的那个P吃掉,那么贪心策略就很简单了:每次在二分出来的mid时间内,由最左侧的P吃掉最左侧*就可。
但是同时我们也需要考虑特殊情况,例如:
*..P.*

这样子P肯定是先吃一侧的再吃另一侧的,那么总时间是应该是先吃左侧的再吃右侧的这样花费时间最少。其实时间花费应该是两个*之间的间距+min(P和左侧*的间距,P和右侧*之间的间距).

那么思路就很明确了:利用优先队列(小根堆)每次只需要找出最左侧的*查看当前遍历到的P能否吃掉它,如果能吃掉就弹出堆,最后能全部吃完就返回true便可。

代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N=1e6+100;

priority_queue<int,vector<int>,greater<int>>q;
vector<int>res;
bool check(int x){
	auto qq=q;
	for(auto i:res){
		if(qq.empty())break;
		if(i-qq.top()>x)return false;
        //当前遍历到的P不能在限定时间内吃到最左侧的*,那么后续的P都吃不到这个*了,所以我们直接返回false
		int l=qq.top();
        //记录最左侧的*的位置
		while(!qq.empty()&&qq.top()<i)qq.pop();
        //如果当前P能在限定时间内吃到这个*,那么就把它弹出堆
		while(!qq.empty()&&qq.top()-l+min(abs(qq.top()-i),abs(i-l))<=x)qq.pop();
        //当前P可以先吃一侧的再吃另一侧的
	}
	if(qq.empty())//吃完了
		return true;
	return false;
}
void solve(){
	int n;
	cin>>n;
	string s;
	cin>>s;
	for(int i=1;i<=n;i++)
	{
		if(s[i-1]=='*')q.push(i);
		else if(s[i-1]=='P')res.push_back(i);
	}
	ll l=1,r=1e9,ans=l;
	while(l<=r){
		int mid=l+r>>1;
		if(check(mid)){
			ans=mid,r=mid-1;
		}
		else l=mid+1;
	}
	cout<<ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	//	cin>>t;
	while(t--)
		solve();
	return 0;
}

标签:吃掉,位置,星号,单元格,2024,时间,zstu,游戏场地,Packmen
From: https://www.cnblogs.com/myy-zzb/p/18304831

相关文章

  • 2024最新的源代码防泄漏方案分享
    源代码是软件开发的核心资产,一旦泄露,不仅会导致知识产权损失,还可能被竞争对手利用,给企业带来巨大的经济损失和法律风险。那么有没有针对源代码的防泄漏方案呢?接下来我为大家介绍2024最新的源代码防泄漏解决方案。1.访问控制:实施严格的访问控制策略,确保只有授权的开发者和......
  • 【2024-07-15】欠债人生
    23:59如果你在这世上、在你自身之外去寻找幸福,那任何东西都不会有幸福的影子。对于幸福,我们既不能争论,也无法预测,此时此刻拥有的幸福才是幸福。如果幸福看似还在未来,那就停下来想一想,因为你已经拥有它了。有希望就是一种幸福。                ......
  • 2024开放式耳机品牌榜,小白可以直入的五款蓝牙耳机!
    在选择适合散步聊天和听歌的耳机时,开放式耳机确实是一个值得考虑的选项。与传统的入耳式耳机相比,开放式耳机最大的优势在于它们不会完全封闭耳道,因此用户在享受音乐的同时,仍能保持对周围环境的感知,这对于户外活动尤其重要,因为它可以提高安全性,让你在散步或跑步时能够听到交通声......
  • 2024年度上半年中国汽车保值率报告
    来源:中国汽车流通协会&精真估近期历史回顾:2024上半年房地产企业数智化转型报告.pdf2024国产院线电影路演数据洞察报告.pdf空间数据智能大模型研究-2024年中国空间数据智能战略发展白皮书.pdf2024年全球资产管理报告2024年中型律师事务所的法律趋势.pdf2024年数字经济报......
  • 题解:P10724 [GESP202406 七级] 区间乘积
    思路看到\(a_i\)很小,不难想到状压一类的东西。考虑把每个数的质因数当做二进制位,这个二进制位的\(1/0\)代表含有这个质因数的奇偶,再做一个异或前缀和,显然完全平方数的质因子个数一定为偶数,根据异或的性质,两个相同的数异或才为\(0\)所以只需要找到异或前缀和中相同的数的个......
  • 【专题】2024医疗健康行业报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=36465原文出处:拓端数据部落公众号根据国家统计局的数据和业界预测,2022年我国医药工业市场规模已攀升至约2.9万亿元,并预计至2030年,规模以上医药工业企业的收入将突破4.8万亿元,实现年复合增长率约6.5%的稳健增长。过去三年,新冠疫情为医疗行业带来了......
  • Spark _Exam_ 20240715
    SparkExam20240715ConclusionSB出题人出DP场,T1靠小常数通过不给提示干死选手,T2出题人认为思维难度低代码5KB,NOIP场的T3放黑题,T4又是区间DP\(\mathcalO(n^6)=117649000000\)竟然能够通过?你代码常数真的小!好的喷完了。这种场的后果就是,平均分50,最高90,最低0实际上如......
  • .NET周刊【7月第2期 2024-07-14】
    国内文章开源GTKSystem.Windows.Forms框架让C#winform支持跨平台运行https://www.cnblogs.com/easywebfactory/p/18289178GTKSystem.Windows.Forms框架是一种C#winform应用程序跨平台界面开发框架,兼容C#原生控件,无需额外学习,支持跨平台运行。其优势包括开源、与visualstudio......
  • [考试记录] 2024.7.15 csp-s模拟赛4
    2024.7.15csp-s模拟赛4T1传送带题面翻译有一个长度为\(n\)的一维网格。网格的第\(i\)个单元格包含字符\(s_i\),是“<”或“>”。当弹球放在其中一个格子上时,它会按照以下规则移动:如果弹球位于第\(i\)个格子上且\(s_i\)为'<',则弹球在下一秒会向左移动一个单元格;如......
  • Codeforces Round #956 (Div. 2) and ByteRace 2024
    目录写在前面ABCDEF写在最后写在前面比赛地址:https://codeforces.com/contest/1983孩子们我回来了。这场实在是太对胃口,vp不到1h就4题了之后EF也口出来了,然而赛时睡大觉去了没打真是亏死。感觉自己的文字能力已经很牛逼了,不需要再多练了,以后的题解都会写得简略些。A......