社区讨论

Div.3 基础赛 T4 80 分 WA on Sub 1 #2 求调

题目总版参与者 5已保存回复 14

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
12 条
当前快照
1 份
快照标识符
@mlj9gvg3
此快照首次捕获于
2026/02/12 17:33
7 天前
此快照最后确认于
2026/02/14 23:55
5 天前
查看原帖
调红温了,拼尽全力无法战胜,求救。
思路是计算往两边走,回/不回来的收益,然后特判,实在找不到 hack 了,对拍都拍不动了QWQ
写一半彻底怒了,所以我把大部分地方都加了注释。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=2e6+5;
int a[N],tim[N];
int n,st,d,id;

inline int read(){
	int s=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s;
}

signed main(){
	cin>>n>>st>>d;n--;
	for(int i=1;i<=n;i++) a[i]=read(),tim[i]=(a[i]-2)/(2*d);//需要留两个,防止怪物/人叠在一起
//	for(int i=1;i<=n;i++) cout<<tim[i]<<" ";
	int pre=(a[st]-1)/(2*d);
//	for(int i=1;i<=n;i++) cout<<tim[i]<<" ";
//	cout<<"\n\n\n";
	//1.左边跑一半 
	id=1;int ans1=0;//ans1 是左边跑一半
	for(int i=st-1;i>=2;i--)
		if(tim[i]+tim[i-1]<=1){id=i-1;break;}//如果连续两个不支持回来,必须直接离开 
	for(int i=st-1;i>=id;i--) ans1+=tim[i];
	//2.左边跑到底
	id=1;int ans2=0;//ans2 是左边跑到底
	for(int i=st-1;i>=2;i--)
		if(tim[i]==0 && tim[i-1]==0){id=i-1;break;}//再往下就走不了了,结束 
	for(int i=st-1;i>=id;i--) ans2+=tim[i];
//	cout<<id<<"\n"; 
	//3.右边跑一半 
	id=n;int ans3=0;//ans3 是右边跑一半 
	for(int i=st+1;i<n;i--)
		if(tim[i]+tim[i+1]<=1){id=i+1;break;}//如果连续两个都不支持回来,必须直接离开  
	for(int i=st+1;i<=id;i++) ans3+=tim[i];
	//4.右边跑到底
	id=n;int ans4=0;//ans4 是右边跑到底
	for(int i=st+1;i<n;i++)
		if(tim[i]==0 && tim[i+1]==0){id=i+1;break;}//再往下就走不了了,结束  
	for(int i=st+1;i<=id;i++) ans4+=tim[i];
	//统计答案要带上 st 
	if(tim[st-1]==0 && tim[st]==0) cout<<max(ans2,ans4)+pre;//左边回不来 
	else if(tim[st]==0 && tim[st+1]==0) cout<<max(ans2,ans1)+pre;//右边回不来 
	else if(tim[st-1]>1 && tim[st+1]>1) cout<<pre+max(ans1+ans4,ans2+ans3);//起点可以直接等到底 
	else cout<<max((tim[st]+max(ans1+ans4,ans2+ans3)),pre+max(ans2,ans4));//有一边可以回来,取 max 
	return 0;
}

回复

14 条回复,欢迎继续交流。

正在加载回复...