CF1872B The Corridor or There and Back Again

发布时间 2023-10-15 16:56:30作者: Natori

CF1872B The Corridor or There and Back Again

观察第二组样例的解释,注意这句话:“第二个陷阱限制了你”。这启发我们计算经过每个陷阱之后最多还能向前走到哪里,然后取 \(\min\) 得到答案。

现在的问题是如何求出每个陷阱限制的最远可到达点。

由于要求折返,因此对于第 \(i\) 个陷阱,它限制的最远可到达点为 \(d_i+\lfloor\dfrac{s_i}{2}\rfloor\)。同时注意到要求“返回时间严格小于 \(s_i\)”,所以对于偶数,直接除以 \(2\) 并向下取整是不行的,要先让 \(s_i\) 自减 \(1\)

时间复杂度 \(\mathcal{O}(n)\)

代码:

#include<bits/stdc++.h>
using namespace std;
bool Mbegin;
void File_Work(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
}
namespace Fast_In_Out{
	char buf[1<<21],*P1=buf,*P2=buf;
	#define gc (P1==P2&&(P2=(P1=buf)+fread(buf,1,1<<21,stdin),P1==P2)?EOF:*P1++)
	int read(){
		int f=1,x=0;
		char c=gc;
		while(c<'0'||c>'9'){
			if(c=='-')
			    f=-1;
			c=gc;
		}
		while(c>='0'&&c<='9'){
			x=x*10+c-'0';
			c=gc;
		}
		return f*x;
	}
	void write(int x){
		if(x<0)
			x=-x,putchar('-');
		if(x>9)
			write(x/10);
		putchar(x%10+'0');
	}
	#undef gc
}
using namespace Fast_In_Out;
const int N=108,oo=1e9+8;
int n,a[N];
void solve(){
	n=read();
	int ans=oo;
	for(int i=1;i<=n;i++){
		int d=read(),s=read();
		if(s%2==0)
			s--;
		ans=min(ans,d+s/2);
	}
	write(ans),putchar('\n'); 
}
bool Mend;
int main(){
	fprintf(stderr,"%.3lf MB\n\n\n",(&Mbegin-&Mend)/1048576.0);
	int testnum=read();
	while(testnum--)
		solve();	
	fprintf(stderr,"\n\n\n%.0lf ms",1e3*clock()/CLOCKS_PER_SEC);
	return 0;
}